Followup-For: 414134 Tags: patch link for diff's between 0.10.3 an 0.10.3.1:
http://trac.edgewall.org/changeset/4949 http://trac.edgewall.org/changeset/4949?format=diff&new=4949 stripped diff (only has the fixes) is attached.
Index: trac/attachment.py =================================================================== --- trac/attachment.py (revision 4383) +++ trac/attachment.py (revision 4949) @@ -292,8 +292,8 @@ render_unsafe_content = BoolOption('attachment', 'render_unsafe_content', 'false', - """Whether non-binary attachments should be rendered in the browser, or + """Whether attachments should be rendered in the browser, or only made downloadable. - Pretty much any text file may be interpreted as HTML by the browser, + Pretty much any file may be interpreted as HTML by the browser, which allows a malicious user to attach a file containing cross-site scripting attacks. @@ -556,20 +556,22 @@ format = req.args.get('format') if format in ('raw', 'txt'): - if not self.render_unsafe_content and not binary: - # Force browser to download HTML/SVG/etc pages that may - # contain malicious code enabling XSS attacks - req.send_header('Content-Disposition', 'attachment;' + - 'filename=' + attachment.filename) - if not mime_type or (self.render_unsafe_content and \ - not binary and format == 'txt'): - mime_type = 'text/plain' + if not self.render_unsafe_content: + # Force browser to download files instead of rendering + # them, since they might contain malicious code enabling + # XSS attacks + req.send_header('Content-Disposition', 'attachment') + if format == 'txt': + mime_type = 'text/plain' + elif not mime_type: + mime_type = 'application/octet-stream' if 'charset=' not in mime_type: charset = mimeview.get_charset(str_data, mime_type) mime_type = mime_type + '; charset=' + charset + req.send_file(attachment.path, mime_type) # add ''Plain Text'' alternate link if needed - if self.render_unsafe_content and not binary and \ - mime_type and not mime_type.startswith('text/plain'): + if (self.render_unsafe_content and + mime_type and not mime_type.startswith('text/plain')): plaintext_href = attachment.href(req, format='txt') add_link(req, 'alternate', plaintext_href, 'Plain Text', Index: trac/mimeview/api.py =================================================================== --- trac/mimeview/api.py (revision 4380) +++ trac/mimeview/api.py (revision 4949) @@ -605,6 +605,6 @@ req.send_response(200) req.send_header('Content-Type', output_type) - req.send_header('Content-Disposition', 'filename=%s.%s' % (filename, - ext)) + req.send_header('Content-Disposition', 'attachment; filename=%s.%s' % + (filename, ext)) req.end_headers() req.write(content) Index: trac/versioncontrol/web_ui/browser.py =================================================================== --- trac/versioncontrol/web_ui/browser.py (revision 3618) +++ trac/versioncontrol/web_ui/browser.py (revision 4949) @@ -22,5 +22,5 @@ from trac import util -from trac.config import ListOption, Option +from trac.config import ListOption, BoolOption, Option from trac.core import * from trac.mimeview import Mimeview, is_binary, get_mimetype @@ -58,4 +58,16 @@ (''since 0.10'')""") + render_unsafe_content = BoolOption('browser', 'render_unsafe_content', + 'false', + """Whether attachments should be rendered in the browser, or + only made downloadable. + + Pretty much any file may be interpreted as HTML by the browser, + which allows a malicious user to attach a file containing cross-site + scripting attacks. + + For public sites where anonymous users can create attachments it is + recommended to leave this option disabled (which is the default).""") + # INavigationContributor methods @@ -217,4 +229,9 @@ req.send_header('Content-Length', node.content_length) req.send_header('Last-Modified', http_date(node.last_modified)) + if not self.render_unsafe_content: + # Force browser to download files instead of rendering + # them, since they might contain malicious code enabling + # XSS attacks + req.send_header('Content-Disposition', 'attachment') req.end_headers()