XSS security fix for advanced search form: added escaping (thanks to Emanuele Gentili from Ubuntu for discovering the problem) (ported from 1.7)
1.1 --- a/MoinMoin/macro/AdvancedSearch.py Sun Jun 22 19:19:57 2008 +0200
1.2 +++ b/MoinMoin/macro/AdvancedSearch.py Sun Jul 13 18:54:10 2008 +0200
1.3 @@ -39,14 +39,18 @@
1.4 return pages
1.5
1.6
1.7 -def form_get(request, name, default=''):
1.8 +def form_get(request, name, default='', escaped=False):
1.9 """ Fetches a form field
1.10 -
1.11 +
1.12 @param request: current request
1.13 @param name: name of the field
1.14 - @keyword default: value if not present (default: '')
1.15 + @param default: value if not present (default: '')
1.16 + @param escaped: if True, escape value so it can be used for html generation (default: False)
1.17 """
1.18 - return request.form.get(name, [default])[0]
1.19 + value = request.form.get(name, [default])[0]
1.20 + if escaped:
1.21 + value = wikiutil.escape(value, quote=True)
1.22 + return value
1.23
1.24
1.25 def advanced_ui(macro):
1.26 @@ -78,20 +82,20 @@
1.27 ]) for txt, input_field in (
1.28 (_('containing all the following terms', formatted=False),
1.29 '<input type="text" name="and_terms" size="30" value="%s">'
1.30 - % (form_get(request, 'and_terms') or form_get(request, 'value'))),
1.31 + % (form_get(request, 'and_terms', escaped=True) or form_get(request, 'value', escaped=True))),
1.32 (_('containing one or more of the following terms', formatted=False),
1.33 '<input type="text" name="or_terms" size="30" value="%s">'
1.34 - % form_get(request, 'or_terms')),
1.35 + % form_get(request, 'or_terms', escaped=True)),
1.36 (_('not containing the following terms', formatted=False),
1.37 '<input type="text" name="not_terms" size="30" value="%s">'
1.38 - % form_get(request, 'not_terms')),
1.39 + % form_get(request, 'not_terms', escaped=True)),
1.40 #('containing only one of the following terms',
1.41 # '<input type="text" name="xor_terms" size="30" value="%s">'
1.42 - # % form_get(request, 'xor_terms')),
1.43 + # % form_get(request, 'xor_terms', escaped=True)),
1.44 # TODO: dropdown-box?
1.45 (_('last modified since (e.g. last 2 weeks)', formatted=False),
1.46 '<input type="text" name="mtime" size="30" value="%s">'
1.47 - % form_get(request, 'mtime')),
1.48 + % form_get(request, 'mtime', escaped=True)),
1.49 )])
1.50 ])
1.51
1.52 @@ -137,22 +141,23 @@
1.53 (_('Language', formatted=False), unicode(lang_select), ''),
1.54 (_('File Type', formatted=False), unicode(mt_select), ''),
1.55 ('', html.INPUT(type='checkbox', name='titlesearch',
1.56 - value='1', checked=form_get(request, 'titlesearch'),
1.57 + value='1', checked=form_get(request, 'titlesearch', escaped=True),
1.58 id='titlesearch'),
1.59 '<label for="titlesearch">%s</label>' % _('Search only in titles', formatted=False)),
1.60 ('', html.INPUT(type='checkbox', name='case', value='1',
1.61 - checked=form_get(request, 'case'), id='case'),
1.62 + checked=form_get(request, 'case', escaped=True),
1.63 + id='case'),
1.64 '<label for="case">%s</label>' % _('Case-sensitive search', formatted=False)),
1.65 ('', html.INPUT(type='checkbox', name='excludeunderlay',
1.66 - value='1', checked=form_get(request, 'excludeunderlay'),
1.67 + value='1', checked=form_get(request, 'excludeunderlay', escaped=True),
1.68 id='excludeunderlay'),
1.69 '<label for="excludeunderlay">%s</label>' % _('Exclude underlay', formatted=False)),
1.70 ('', html.INPUT(type='checkbox', name='nosystemitems',
1.71 - value='1', checked=form_get(request, 'nosystemitems'),
1.72 + value='1', checked=form_get(request, 'nosystemitems', escaped=True),
1.73 id='nosystempages'),
1.74 '<label for="nosystempages">%s</label>' % _('No system items', formatted=False)),
1.75 ('', html.INPUT(type='checkbox', name='historysearch',
1.76 - value='1', checked=form_get(request, 'historysearch'),
1.77 + value='1', checked=form_get(request, 'historysearch', escaped=True),
1.78 disabled=(not request.cfg.xapian_search or
1.79 not request.cfg.xapian_index_history),
1.80 id='historysearch'),