diff options
| author | Chris McDonough <chrism@plope.com> | 2011-09-08 00:25:18 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-09-08 00:25:18 -0400 |
| commit | 4085128ffce32e919265c5adc56a5062a91a8708 (patch) | |
| tree | b21b36cba471f01bec784972e6ce575390b6d077 | |
| parent | 1f085837350df56b5485085ed617360be20c2540 (diff) | |
| parent | d5dc5dd60e3bbff904a67dd02b4aff9226389942 (diff) | |
| download | pyramid-4085128ffce32e919265c5adc56a5062a91a8708.tar.gz pyramid-4085128ffce32e919265c5adc56a5062a91a8708.tar.bz2 pyramid-4085128ffce32e919265c5adc56a5062a91a8708.zip | |
Merge branch 'fix.staticencoding'
| -rw-r--r-- | CHANGES.txt | 6 | ||||
| -rw-r--r-- | pyramid/static.py | 11 | ||||
| -rw-r--r-- | pyramid/tests/fixtures/static/.hiddenfile | 2 | ||||
| -rw-r--r-- | pyramid/tests/fixtures/static/héhé.html | 1 | ||||
| -rw-r--r-- | pyramid/tests/fixtures/static/héhé/index.html | 1 | ||||
| -rw-r--r-- | pyramid/tests/test_integration.py | 21 |
6 files changed, 36 insertions, 6 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index d2af41876..fda27592f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,6 +8,12 @@ Bug Fixes translations (``de``) would not work properly when using a localizer. See https://github.com/Pylons/pyramid/issues/263 +- The static file serving machinery could not serve files that started with a + ``.`` (dot) character (hidden files). + +- The static file serving machinery inappropriately URL-quoted path segments + in filenames when asking for files from the filesystem. + Documentation ------------- diff --git a/pyramid/static.py b/pyramid/static.py index 357fe8014..128d2ce60 100644 --- a/pyramid/static.py +++ b/pyramid/static.py @@ -169,12 +169,13 @@ class static_view(object): url = url + '?' + qs return HTTPMovedPermanently(url) +has_insecure_pathelement = set(['..', '.', '/', '']).intersection + @lru_cache(1000) def _secure_path(path_tuple): - if '' in path_tuple: + if has_insecure_pathelement(path_tuple): return None for item in path_tuple: - for val in ['.', '/']: - if item.startswith(val): - return None - return '/'.join([quote_path_segment(x) for x in path_tuple]) + if '../' in item: + return None + return '/'.join([x.encode('utf-8') for x in path_tuple]) diff --git a/pyramid/tests/fixtures/static/.hiddenfile b/pyramid/tests/fixtures/static/.hiddenfile new file mode 100644 index 000000000..86d345000 --- /dev/null +++ b/pyramid/tests/fixtures/static/.hiddenfile @@ -0,0 +1,2 @@ +<html>I'm hidden</html> + diff --git a/pyramid/tests/fixtures/static/héhé.html b/pyramid/tests/fixtures/static/héhé.html new file mode 100644 index 000000000..fe5e9af50 --- /dev/null +++ b/pyramid/tests/fixtures/static/héhé.html @@ -0,0 +1 @@ +<html>hehe file</html> diff --git a/pyramid/tests/fixtures/static/héhé/index.html b/pyramid/tests/fixtures/static/héhé/index.html new file mode 100644 index 000000000..67623d866 --- /dev/null +++ b/pyramid/tests/fixtures/static/héhé/index.html @@ -0,0 +1 @@ +<html>hehe</html> diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index cd259b630..b78cddf4f 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -70,6 +70,23 @@ class TestStaticAppBase(IntegrationBase): res = self.testapp.get('/minimal.pt', status=200) self._assertBody(res.body, os.path.join(here, 'fixtures/minimal.pt')) + def test_hidden(self): + res = self.testapp.get('/static/.hiddenfile', status=200) + self._assertBody(res.body, os.path.join(here, + 'fixtures/static/.hiddenfile')) + + def test_highchars_in_pathelement(self): + res = self.testapp.get('/static/h\xc3\xa9h\xc3\xa9/index.html', + status=200) + self._assertBody(res.body, os.path.join( + here, 'fixtures/static/h\xc3\xa9h\xc3\xa9/index.html')) + + def test_highchars_in_filename(self): + res = self.testapp.get('/static/h\xc3\xa9h\xc3\xa9.html', + status=200) + self._assertBody(res.body, os.path.join( + here, 'fixtures/static/h\xc3\xa9h\xc3\xa9.html')) + def test_not_modified(self): self.testapp.extra_environ = { 'HTTP_IF_MODIFIED_SINCE':httpdate(pow(2, 32)-1)} @@ -140,7 +157,9 @@ class TestStaticAppBase(IntegrationBase): def test_oob_slash(self): self.testapp.get('/%2F/test_integration.py', status=404) - # XXX pdb this + + def test_oob_dotdotslash_encoded(self): + self.testapp.get('/static/%2E%2E%2F/test_integration.py', status=404) class TestStaticAppUsingAbsPath(TestStaticAppBase, unittest.TestCase): |
