Commits

jamalex committed 5306720

Added check to prevent serving media above the media root path.

Comments (2)

  1. tdussmann

    on windows, depending on how the appropriate variable is configured in the settings, I get permission denied on every static file

    explanation: I am defining file urls relative to the project directory, now like this:

    STATIC_ROOT = PROJECT_PATH + r'\static'
    

    the django documentation states however, to put forward slashes also on windows, obviously because normally the backslashes would simply be cause the following character to be escaped. so the resulting path has been something like this: C:\Users\myuser\workspace\Project/static/ which does NOT match your "startswith" check , as this compares the two strings literally.

    should the media_root (actually static_root) path be normalized to prevent this? i.e. to contain only one kind of slashes or will everybody who has this problem figure it out on his own?

    again, this happens on windows, because of the use of backslashes, which we normally don't need to use within python, as they are normally treated correctly (by builtin runserver at least).

Files changed (1)

django_wsgiserver/mediahandler.py

         path_info = environ['PATH_INFO']
         if path_info[0] == '/':
             path_info = path_info[1:]
-        # this is the thing I'm not sure is secure, can we prevent
-        # going up outof media root?
-        file_path = os.path.join( self.media_root, path_info )
+        file_path = os.path.normpath( os.path.join( self.media_root, path_info ) )
+
+        # prevent escaping out of paths below media root (e.g. via "..")
+        if not file_path.startswith( self.media_root ):
+            status = '401 UNAUTHORIZED'
+            headers = {'Content-type': 'text/plain'}
+            output = ['Permission denied: %s' % file_path]
+            return done( status, headers, output )
 
         if not os.path.exists( file_path ):
             status = '404 NOT FOUND'