some changes to the web UI to defend against XSS
This commit is contained in:
parent
182a179a52
commit
d4836ac43c
4 changed files with 59 additions and 27 deletions
|
|
@ -414,6 +414,18 @@ def hello(req):
|
|||
def showSession(req):
|
||||
return _getServer(req).showSession()
|
||||
|
||||
# All Tasks
|
||||
_TASKS = ['build',
|
||||
'buildSRPMFromSCM',
|
||||
'buildArch',
|
||||
'chainbuild',
|
||||
'waitrepo',
|
||||
'tagBuild',
|
||||
'newRepo',
|
||||
'createrepo',
|
||||
'buildNotification',
|
||||
'tagNotification',
|
||||
'dependantTask']
|
||||
# Tasks that can exist without a parent
|
||||
_TOPLEVEL_TASKS = ['build', 'buildNotification', 'chainbuild', 'newRepo', 'tagBuild', 'tagNotification', 'waitrepo']
|
||||
# Tasks that can have children
|
||||
|
|
@ -437,6 +449,13 @@ def tasks(req, owner=None, state='active', view='tree', method='all', hostID=Non
|
|||
|
||||
values['users'] = server.listUsers(queryOpts={'order': 'name'})
|
||||
|
||||
if method in _TASKS:
|
||||
opts['method'] = method
|
||||
else:
|
||||
method = 'all'
|
||||
values['method'] = method
|
||||
values['alltasks'] = _TASKS
|
||||
|
||||
treeEnabled = True
|
||||
if hostID or (method not in ['all'] + _PARENT_TASKS):
|
||||
# force flat view if we're filtering by a hostID or a task that never has children
|
||||
|
|
@ -462,10 +481,6 @@ def tasks(req, owner=None, state='active', view='tree', method='all', hostID=Non
|
|||
treeDisplay = False
|
||||
values['treeDisplay'] = treeDisplay
|
||||
|
||||
if method != 'all':
|
||||
opts['method'] = method
|
||||
values['method'] = method
|
||||
|
||||
if view in ('tree', 'toplevel'):
|
||||
opts['parent'] = None
|
||||
|
||||
|
|
@ -721,6 +736,8 @@ def tags(req, start=None, order=None, childID=None):
|
|||
|
||||
return _genHTML(req, 'tags.chtml')
|
||||
|
||||
_PREFIX_CHARS = [chr(char) for char in range(48, 58) + range(97, 123)]
|
||||
|
||||
def packages(req, tagID=None, userID=None, order='package_name', start=None, prefix=None, inherited='1'):
|
||||
values = _initValues(req, 'Packages', 'packages')
|
||||
server = _getServer(req)
|
||||
|
|
@ -738,7 +755,9 @@ def packages(req, tagID=None, userID=None, order='package_name', start=None, pre
|
|||
values['user'] = user
|
||||
values['order'] = order
|
||||
if prefix:
|
||||
prefix = prefix.lower()
|
||||
prefix = prefix.lower()[0]
|
||||
if prefix not in _PREFIX_CHARS:
|
||||
prefix = None
|
||||
values['prefix'] = prefix
|
||||
inherited = int(inherited)
|
||||
values['inherited'] = inherited
|
||||
|
|
@ -747,7 +766,7 @@ def packages(req, tagID=None, userID=None, order='package_name', start=None, pre
|
|||
kw={'tagID': tagID, 'userID': userID, 'prefix': prefix, 'inherited': bool(inherited)},
|
||||
start=start, dataName='packages', prefix='package', order=order)
|
||||
|
||||
values['chars'] = [chr(char) for char in range(48, 58) + range(97, 123)]
|
||||
values['chars'] = _PREFIX_CHARS
|
||||
|
||||
return _genHTML(req, 'packages.chtml')
|
||||
|
||||
|
|
@ -1110,7 +1129,9 @@ def builds(req, userID=None, tagID=None, packageID=None, state=None, order='-com
|
|||
values['state'] = state
|
||||
|
||||
if prefix:
|
||||
prefix = prefix.lower()
|
||||
prefix = prefix.lower()[0]
|
||||
if prefix not in _PREFIX_CHARS:
|
||||
prefix = None
|
||||
values['prefix'] = prefix
|
||||
|
||||
values['order'] = order
|
||||
|
|
@ -1135,7 +1156,7 @@ def builds(req, userID=None, tagID=None, packageID=None, state=None, order='-com
|
|||
'state': state, 'prefix': prefix},
|
||||
start=start, dataName='builds', prefix='build', order=order)
|
||||
|
||||
values['chars'] = [chr(char) for char in range(48, 58) + range(97, 123)]
|
||||
values['chars'] = _PREFIX_CHARS
|
||||
|
||||
return _genHTML(req, 'builds.chtml')
|
||||
|
||||
|
|
@ -1144,7 +1165,9 @@ def users(req, order='name', start=None, prefix=None):
|
|||
server = _getServer(req)
|
||||
|
||||
if prefix:
|
||||
prefix = prefix.lower()
|
||||
prefix = prefix.lower()[0]
|
||||
if prefix not in _PREFIX_CHARS:
|
||||
prefix = None
|
||||
values['prefix'] = prefix
|
||||
|
||||
values['order'] = order
|
||||
|
|
@ -1152,7 +1175,7 @@ def users(req, order='name', start=None, prefix=None):
|
|||
users = kojiweb.util.paginateMethod(server, values, 'listUsers', kw={'prefix': prefix},
|
||||
start=start, dataName='users', prefix='user', order=order)
|
||||
|
||||
values['chars'] = [chr(char) for char in range(48, 58) + range(97, 123)]
|
||||
values['chars'] = _PREFIX_CHARS
|
||||
|
||||
return _genHTML(req, 'users.chtml')
|
||||
|
||||
|
|
@ -1848,10 +1871,15 @@ _infoURLs = {'package': 'packageinfo?packageID=%(id)i',
|
|||
'host': 'hostinfo?hostID=%(id)i',
|
||||
'rpm': 'rpminfo?rpmID=%(id)i',
|
||||
'file': 'fileinfo?rpmID=%(id)i&filename=%(name)s'}
|
||||
|
||||
|
||||
_VALID_SEARCH_CHARS = r"""a-zA-Z0-9"""
|
||||
_VALID_SEARCH_SYMS = r"""@.,_/\()%+-*?|[]^$"""
|
||||
_VALID_SEARCH_RE = re.compile('^[' + _VALID_SEARCH_CHARS + re.escape(_VALID_SEARCH_SYMS) + ']+$')
|
||||
|
||||
def search(req, start=None, order='name'):
|
||||
values = _initValues(req, 'Search', 'search')
|
||||
server = _getServer(req)
|
||||
values['error'] = None
|
||||
|
||||
form = req.form
|
||||
if form.has_key('terms') and form['terms']:
|
||||
|
|
@ -1862,12 +1890,19 @@ def search(req, start=None, order='name'):
|
|||
values['type'] = type
|
||||
values['match'] = match
|
||||
|
||||
if not _VALID_SEARCH_RE.match(terms):
|
||||
values['error'] = 'Invalid search terms<br/>' + \
|
||||
'Search terms may contain only these characters: ' + \
|
||||
_VALID_SEARCH_CHARS + _VALID_SEARCH_SYMS
|
||||
return _genHTML(req, 'search.chtml')
|
||||
|
||||
if match == 'regexp':
|
||||
try:
|
||||
re.compile(terms)
|
||||
except:
|
||||
raise koji.GenericError, 'invalid regular expression: %s' % terms
|
||||
|
||||
values['error'] = 'Invalid regular expression'
|
||||
return _genHTML(req, 'search.chtml')
|
||||
|
||||
infoURL = _infoURLs.get(type)
|
||||
if not infoURL:
|
||||
raise koji.GenericError, 'unknown search type: %s' % type
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
<form action="search">
|
||||
<table>
|
||||
<tr>
|
||||
#if $error
|
||||
<tr><td colspan="3" class="error">$error</td></tr>
|
||||
#end if
|
||||
<th>Search</th>
|
||||
<td><input type="text" name="terms"/></td>
|
||||
<td>
|
||||
|
|
@ -26,7 +29,7 @@
|
|||
<td colspan="2">
|
||||
<input type="radio" name="match" value="glob" id="radioglob" checked="checked"/><abbr title="? will match any single character, * will match any sequence of zero or more characters" id="abbrglob">glob</abbr>
|
||||
<input type="radio" name="match" value="regexp" id="radioregexp"/><abbr title="full POSIX regular expressions" id="abbrregexp">regexp</abbr>
|
||||
<input type="radio" name="match" value="exact" id="radioexact"/><abbr title="exact matches only" id="abbrexact">exact</abbr>
|
||||
<input type="radio" name="match" value="exact" id="radioexact"/><abbr title="exact matches only" id="abbrexact">exact</abbr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
|||
|
|
@ -78,19 +78,9 @@ All
|
|||
</td><td>
|
||||
<select name="method" class="filterlist" onchange="javascript: window.location = 'tasks?method=' + this.value + '$util.passthrough_except($self, 'method')';">
|
||||
<option value="all" $util.toggleSelected($self, $method, 'all')>all</option>
|
||||
<option value="build" #if $method == 'build' then 'selected="selected"' else ''#>build</option>
|
||||
<option value="buildSRPMFromSCM" #if $method == 'buildSRPMFromSCM' then 'selected="selected"' else ''#>buildSRPMFromSCM</option>
|
||||
<option value="buildSRPMFromCVS" #if $method == 'buildSRPMFromCVS' then 'selected="selected"' else ''#>buildSRPMFromCVS</option>
|
||||
<option value="buildArch" #if $method == 'buildArch' then 'selected="selected"' else ''#>buildArch</option>
|
||||
<option value="buildNotification" #if $method == 'buildNotification' then 'selected="selected"' else ''#>buildNotification</option>
|
||||
<option value="tagBuild" #if $method == 'tagBuild' then 'selected="selected"' else ''#>tagBuild</option>
|
||||
<option value="tagNotification" #if $method == 'tagNotification' then 'selected="selected"' else ''#>tagNotification</option>
|
||||
<option value="newRepo" #if $method == 'newRepo' then 'selected="selected"' else ''#>newRepo</option>
|
||||
<option value="prepRepo" #if $method == 'prepRepo' then 'selected="selected"' else ''#>prepRepo</option>
|
||||
<option value="createrepo" #if $method == 'createrepo' then 'selected="selected"' else ''#>createrepo</option>
|
||||
<option value="dependantTask" #if $method == 'dependantTask' then 'selected="selected"' else ''#>dependantTask</option>
|
||||
<option value="chainbuild" #if $method == 'chainbuild' then 'selected="selected"' else ''#>chainbuild</option>
|
||||
<option value="waitrepo" #if $method == 'waitrepo' then 'selected="selected"' else ''#>waitrepo</option>
|
||||
#for $task_type in $alltasks
|
||||
<option value="$task_type" #if $method == $task_type then 'selected="selected"' else ''#>$task_type</option>
|
||||
#end for
|
||||
</select>
|
||||
</td><td>
|
||||
<strong>View</strong>:
|
||||
|
|
|
|||
|
|
@ -437,3 +437,7 @@ span#loginInfo {
|
|||
font-size: medium;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue