changeset 1548:2eb5117aa7de

content-disposition for AttachFile downloads either inline or attachment depending on mimetype in cfg.mimetypes_xss_protect list
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Thu, 14 Sep 2006 18:37:05 +0200
parents e74f46dbe7c8
children e36313297589
files MoinMoin/action/AttachFile.py MoinMoin/config/multiconfig.py docs/CHANGES
diffstat 3 files changed, 36 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/AttachFile.py	Thu Sep 14 15:42:23 2006 +0200
+++ b/MoinMoin/action/AttachFile.py	Thu Sep 14 18:37:05 2006 +0200
@@ -666,13 +666,24 @@
         request.emit_http_headers(["Status: 304 Not modified"])
     else:
         mt = wikiutil.MimeType(filename=filename)
+        content_type = mt.content_type()
+        mime_type = mt.mime_type()
+
+        # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
+        # There is no solution that is compatible to IE except stripping non-ascii chars
+        filename_enc = filename.encode(config.charset)
+
+        # for dangerous files (like .html), when we are in danger of cross-site-scripting attacks,
+        # we just let the user store them to disk ('attachment').
+        # For safe files, we directly show them inline (this also works better for IE).
+        dangerous = mime_type in request.cfg.mimetypes_xss_protect
+        content_dispo = dangerous and 'attachment' or 'inline'
+
         request.emit_http_headers([
-            "Content-Type: %s" % mt.content_type(),
-            "Last-Modified: %s" % timestamp, # TODO maybe add a short Expires: header here?
-            "Content-Length: %d" % os.path.getsize(fpath),
-            # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
-            # There is no solution that is compatible to IE except stripping non-ascii chars
-            "Content-Disposition: attachment; filename=\"%s\"" % filename.encode(config.charset),
+            'Content-Type: %s' % content_type,
+            'Last-Modified: %s' % timestamp, # TODO maybe add a short Expires: header here?
+            'Content-Length: %d' % os.path.getsize(fpath),
+            'Content-Disposition: %s; filename="%s"' % (content_dispo, filename_enc),
         ])
 
         # send data
--- a/MoinMoin/config/multiconfig.py	Thu Sep 14 15:42:23 2006 +0200
+++ b/MoinMoin/config/multiconfig.py	Thu Sep 14 18:37:05 2006 +0200
@@ -313,6 +313,14 @@
     mail_import_wiki_address = None # the e-mail address for e-mails that should go into the wiki
     mail_import_secret = ""
 
+    # some dangerous mimetypes (we don't use "content-disposition: inline" for them when a user
+    # downloads such attachments, because the browser might execute e.g. Javascript contained
+    # in the HTML and steal your moin cookie or do other nasty stuff) 
+    mimetypes_xss_protect = [
+        'text/html',
+        'application/x-shockwave-flash',
+    ]
+
     navi_bar = [u'RecentChanges', u'FindPage', u'HelpContents', ]
     nonexist_qm = False
 
--- a/docs/CHANGES	Thu Sep 14 15:42:23 2006 +0200
+++ b/docs/CHANGES	Thu Sep 14 18:37:05 2006 +0200
@@ -271,6 +271,17 @@
       homepages anymore.
     * Now multiple formatters can be used per request, the send_page code was
       not reentrant to this regard. Fixes "empty" search results.
+    * Not a moin bug, but it severely annoyed IE users and also was less
+      comfortable for users of other browser: since about 1.5.4, we served
+      attachments with Content-Disposition: attachment - so that the user has
+      to save them to disk. This was to fix a possible XSS attack using attached
+      HTML files with Javascript inside for stealing your moin cookie or doing
+      other nasty things. We improved this by using different behaviour depending
+      on the potential danger the attached file has when served inline:
+      mimetypes_xss_protect = ['text/html', 'application/x-shockwave-flash', ]
+      This is the default value. If you know more dangerous stuff, please just
+      add the mimetypes there to protect your users and file a bug report
+      telling us what we missed.
 
   Other changes:
     * HINT: instead of "from MoinMoin.multiconfig import DefaultConfig" you