Merge pull request #510 from dannon/whitelist_tools

Whitelist for tools
This commit is contained in:
carlfeberhard
2015-07-28 16:44:40 -04:00
7 changed files with 108 additions and 1 deletions
+6
View File
@@ -643,6 +643,12 @@ nglims_config_file = tool-data/nglims.yaml
# make the Galaxy instance susceptible to XSS attacks initiated by your users.
#sanitize_all_html = True
# Whitelist sanitization file.
# Datasets created by tools listed in this file are trusted and will not have
# their HTML sanitized on display. This can be manually edited or manipulated
# through the Admin control panel -- see "Manage Display Whitelist"
#sanitize_whitelist_file = config/sanitize_whitelist.txt
# By default Galaxy will serve non-HTML tool output that may potentially
# contain browser executable JavaScript content as plain text. This will for
# instance cause SVG datasets to not render properly and so may be disabled
+12
View File
@@ -252,6 +252,8 @@ class Configuration( object ):
self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) )
self.log_events = string_as_bool( kwargs.get( 'log_events', 'False' ) )
self.sanitize_all_html = string_as_bool( kwargs.get( 'sanitize_all_html', True ) )
self.sanitize_whitelist_file = resolve_path( kwargs.get( 'sanitize_whitelist_file', "config/sanitize_whitelist.txt" ), self.root )
self.reload_sanitize_whitelist()
self.serve_xss_vulnerable_mimetypes = string_as_bool( kwargs.get( 'serve_xss_vulnerable_mimetypes', False ) )
self.trust_ipython_notebook_conversion = string_as_bool( kwargs.get( 'trust_ipython_notebook_conversion', False ) )
self.enable_old_display_applications = string_as_bool( kwargs.get( "enable_old_display_applications", "True" ) )
@@ -470,6 +472,16 @@ class Configuration( object ):
else:
return None
def reload_sanitize_whitelist( self ):
self.sanitize_whitelist = []
try:
with open(self.sanitize_whitelist_file, 'rt') as f:
for line in f.readlines():
if not line.startswith("#"):
self.sanitize_whitelist.append(line.strip())
except IOError:
log.warning("Sanitize log file %s does not exist, continuing with no tools whitelisted.")
def __parse_config_file_options( self, kwargs ):
"""
Backwards compatibility for config files moved to the config/ dir.
+4
View File
@@ -371,6 +371,10 @@ class Data( object ):
if not preview or isinstance(data.datatype, datatypes.images.Image) or os.stat( data.file_name ).st_size < max_peek_size:
if trans.app.config.sanitize_all_html and trans.response.get_content_type() == "text/html":
# Sanitize anytime we respond with plain text/html content.
# Check to see if this dataset's parent job is whitelisted
# We cannot currently trust imported datasets for rendering.
if not data.creating_job.imported and data.creating_job.tool_id in trans.app.config.sanitize_whitelist:
return open(data.file_name).read()
return sanitize_html(open( data.file_name ).read())
return open( data.file_name )
else:
+7 -1
View File
@@ -62,6 +62,11 @@ def reload_display_application(app, **kwargs):
app.datatypes_registry.reload_display_applications( display_application_ids)
def reload_sanitize_whitelist(app):
log.debug("Executing reload sanitize whitelist control task.")
app.config.reload_sanitize_whitelist()
def reload_tool_data_tables(app, **kwargs):
params = util.Params(kwargs)
log.debug("Executing tool data table reload for %s" % params.get('table_names', 'all tables'))
@@ -80,7 +85,8 @@ def admin_job_lock(app, **kwargs):
control_message_to_task = { 'reload_tool': reload_tool,
'reload_display_application': reload_display_application,
'reload_tool_data_tables': reload_tool_data_tables,
'admin_job_lock': admin_job_lock}
'admin_job_lock': admin_job_lock,
'reload_sanitize_whitelist': reload_sanitize_whitelist}
class GalaxyQueueWorker(ConsumerMixin, threading.Thread):
+19
View File
@@ -1123,6 +1123,25 @@ class Admin( object ):
job=job,
message="<a href='jobs'>Back</a>" )
@web.expose
@web.require_admin
def sanitize_whitelist( self, trans, submit_whitelist=False, tools_to_whitelist=[]):
if submit_whitelist:
# write the configured sanitize_whitelist_file with new whitelist
# and update in-memory list.
with open(trans.app.config.sanitize_whitelist_file, 'wt') as f:
if isinstance(tools_to_whitelist, basestring):
tools_to_whitelist = [tools_to_whitelist]
new_whitelist = sorted([tid for tid in tools_to_whitelist if tid in trans.app.toolbox.tools_by_id])
f.write("\n".join(new_whitelist))
trans.app.config.sanitize_whitelist = new_whitelist
galaxy.queue_worker.send_control_task(trans.app, 'reload_sanitize_whitelist', noop_self=True)
# dispatch a message to reload list for other processes
return trans.fill_template( '/webapps/galaxy/admin/sanitize_whitelist.mako',
sanitize_all=trans.app.config.sanitize_all_html,
tools=trans.app.toolbox.tools_by_id )
# ---- Utility methods -------------------------------------------------------
@@ -74,6 +74,7 @@
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='reload_tool' )}" target="galaxy_main">Reload a tool's configuration</a></div>
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='review_tool_migration_stages' )}" target="galaxy_main">Review tool migration stages</a></div>
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='tool_errors' )}" target="galaxy_main">View Tool Error Logs</a></div>
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='sanitize_whitelist' )}" target="galaxy_main">Manage Display Whitelist</a></div>
</div>
</div>
<div class="toolSectionPad"></div>
@@ -0,0 +1,59 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
%if message:
${render_msg( message, status )}
%endif
%if not sanitize_all:
<div><p>You currently have <strong>sanitize_all_html</strong> set to False
in your galaxy configuration file. This prevents Galaxy from sanitizing
tool outputs, which is an important security feature. For improved
security, we recommend you disable the old-style blanket sanitization and
manage it via this whitelist instead.</p></div>
%else:
<div><p>This interface will allow you to mark particular tools as 'trusted'
after which Galaxy will no longer attempt to sanitize any HTML contents of
datasets created by these tools upon display. Please be aware of the
potential security implications of doing this -- bypassing sanitization
using this whitelist disables Galaxy's security feature (for the indicated
tools) that prevents Galaxy from displaying potentially malicious
Javascript.<br/>
Note that datasets originating from an archive import are still sanitized
even when their creating tool is whitelisted since it isn't possible to
validate the information supplied in the archive.</p></div>
<form name="sanitize_whitelist" action="${h.url_for( controller='admin', action='sanitize_whitelist' )}">
<div class="toolForm">
<div class="toolFormTitle">Tool Sanitization Whitelist</div>
<div class="toolFormBody">
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<th bgcolor="#D8D8D8">Whitelist</th>
<th bgcolor="#D8D8D8">Name</th>
<th bgcolor="#D8D8D8">ID</th>
</tr>
<% ctr = 0 %>
%for tool in tools.values():
%if ctr % 2 == 1:
<tr class="odd_row">
%else:
<tr class="tr">
%endif
<td>
%if tool.id in trans.app.config.sanitize_whitelist:
<input type="checkbox" name="tools_to_whitelist" value="${tool.id}" checked="checked"/>
%else:
<input type="checkbox" name="tools_to_whitelist" value="${tool.id}"/>
%endif
</td>
<td>${ tool.name | h }</td>
<td>${ tool.id | h }</td>
</tr>
<% ctr += 1 %>
%endfor
</table>
</div>
</div>
<input type="submit" name="submit_whitelist" value="Submit new whitelist"/>
</form>
%endif