base_dir = self._language_dir(langs)
full_path = os.path.join(base_dir, path)
+
+ # Block uplevel attacks
+ if not os.path.normpath(full_path).startswith(os.path.normpath(base_dir)):
+ raise cherrypy.HTTPError(403) # Forbidden
+
logger.debug("serving static content: %s", full_path)
if 'Vary' in cherrypy.response.headers:
cherrypy.response.headers['Vary'] = "{}, Accept-Language"
logger.info(self.body)
self.assertIn('<html lang="en">', self.body.decode('utf-8'))
+ @mock.patch(FakeFsMixin.builtins_open, new=FakeFsMixin.f_open)
+ @mock.patch('os.stat', new=FakeFsMixin.f_os.stat)
+ @mock.patch('os.listdir', new=FakeFsMixin.f_os.listdir)
+ def test_home_uplevel_check(self):
+ self._get('/../../../../../../etc/shadow')
+ self.assertStatus(403)
+
@mock.patch(FakeFsMixin.builtins_open, new=FakeFsMixin.f_open)
@mock.patch('os.stat', new=FakeFsMixin.f_os.stat)
@mock.patch('os.listdir', new=FakeFsMixin.f_os.listdir)