diff --git a/rhodecode/controllers/login.py b/rhodecode/controllers/login.py --- a/rhodecode/controllers/login.py +++ b/rhodecode/controllers/login.py @@ -43,7 +43,6 @@ from rhodecode.model.user import UserMod from rhodecode.model.meta import Session - log = logging.getLogger(__name__) @@ -54,7 +53,7 @@ class LoginController(BaseController): def index(self): # redirect if already logged in - c.came_from = request.GET.get('came_from', None) + c.came_from = request.GET.get('came_from') if self.rhodecode_user.is_authenticated \ and self.rhodecode_user.username != 'default': @@ -97,20 +96,20 @@ class LoginController(BaseController): # send set-cookie headers back to response to update cookie headers = [('Set-Cookie', session.request['cookie_out'])] - allowed_schemes = ['http', 'https', 'ftp'] - parsed = urlparse.urlparse(c.came_from) - server_parsed = urlparse.urlparse(url.current()) - - if parsed.scheme and parsed.scheme not in allowed_schemes: - log.error('Suspicious URL scheme detected %s for url %s' % - (parsed.scheme, parsed)) - c.came_from = url('home') - elif server_parsed.netloc != parsed.netloc: - log.error('Suspicious NETLOC detected %s for url %s' - 'server url is: %s' % - (parsed.netloc, parsed, server_parsed)) - c.came_from = url('home') + allowed_schemes = ['http', 'https'] if c.came_from: + parsed = urlparse.urlparse(c.came_from) + server_parsed = urlparse.urlparse(url.current()) + if parsed.scheme and parsed.scheme not in allowed_schemes: + log.error( + 'Suspicious URL scheme detected %s for url %s' % + (parsed.scheme, parsed)) + c.came_from = url('home') + elif server_parsed.netloc != parsed.netloc: + log.error('Suspicious NETLOC detected %s for url %s' + 'server url is: %s' % + (parsed.netloc, parsed, server_parsed)) + c.came_from = url('home') raise HTTPFound(location=c.came_from, headers=headers) else: raise HTTPFound(location=url('home'), headers=headers) diff --git a/rhodecode/tests/functional/test_login.py b/rhodecode/tests/functional/test_login.py --- a/rhodecode/tests/functional/test_login.py +++ b/rhodecode/tests/functional/test_login.py @@ -55,6 +55,25 @@ class TestLoginController(TestController self.assertEqual(response.status, '200 OK') self.assertTrue('Users administration' in response.body) + @parameterized.expand([ + ('data:text/html,',), + ('mailto:test@rhodecode.org',), + ('file:///etc/passwd',), + ('ftp://some.ftp.server',), + ('http://other.domain',), + ]) + def test_login_bad_came_froms(self, url_came_from): + response = self.app.post(url(controller='login', action='index', + came_from=url_came_from), + {'username': 'test_admin', + 'password': 'test12'}) + self.assertEqual(response.status, '302 Found') + self.assertEqual(response._environ['paste.testing_variables'] + ['tmpl_context'].came_from, '/') + response = response.follow() + + self.assertEqual(response.status, '200 OK') + def test_login_short_password(self): response = self.app.post(url(controller='login', action='index'), {'username': 'test_admin',