[Python-modules-commits] [python-social-auth] 88/131: Multiple hosts in redirect sanitaion.
Wolfgang Borgert
debacle at moszumanska.debian.org
Sat Dec 24 15:17:06 UTC 2016
This is an automated email from the git hooks/post-receive script.
debacle pushed a commit to tag v0.2.20
in repository python-social-auth.
commit ed274822027cac1c5be3cd98a129dba1a93c8d20
Author: murchik <murchik at protonmail.com>
Date: Tue Jul 26 23:41:21 2016 +0800
Multiple hosts in redirect sanitaion.
---
social/actions.py | 11 +++++++----
social/tests/test_utils.py | 24 +++++++++++++++++-------
social/utils.py | 10 +++++-----
3 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/social/actions.py b/social/actions.py
index a0e4e5b..0973219 100644
--- a/social/actions.py
+++ b/social/actions.py
@@ -19,8 +19,9 @@ def do_auth(backend, redirect_name='next'):
# Check and sanitize a user-defined GET/POST next field value
redirect_uri = data[redirect_name]
if backend.setting('SANITIZE_REDIRECTS', True):
- redirect_uri = sanitize_redirect(backend.strategy.request_host(),
- redirect_uri)
+ allowed_hosts = backend.setting('ALLOWED_REDIRECT_HOSTS', []) + [
+ backend.strategy.request_host()]
+ redirect_uri = sanitize_redirect(allowed_hosts, redirect_uri)
backend.strategy.session_set(
redirect_name,
redirect_uri or backend.setting('LOGIN_REDIRECT_URL')
@@ -91,8 +92,10 @@ def do_complete(backend, login, user=None, redirect_name='next',
'{0}={1}'.format(redirect_name, redirect_value)
if backend.setting('SANITIZE_REDIRECTS', True):
- url = sanitize_redirect(backend.strategy.request_host(), url) or \
- backend.setting('LOGIN_REDIRECT_URL')
+ allowed_hosts = backend.setting('ALLOWED_REDIRECT_HOSTS', []) + [
+ backend.strategy.request_host()]
+ url = sanitize_redirect(allowed_hosts, url) or \
+ backend.setting('LOGIN_REDIRECT_URL')
return backend.strategy.redirect(url)
diff --git a/social/tests/test_utils.py b/social/tests/test_utils.py
index 7bd8db0..8ab2ead 100644
--- a/social/tests/test_utils.py
+++ b/social/tests/test_utils.py
@@ -13,31 +13,41 @@ PY3 = sys.version_info[0] == 3
class SanitizeRedirectTest(unittest.TestCase):
def test_none_redirect(self):
- self.assertEqual(sanitize_redirect('myapp.com', None), None)
+ self.assertEqual(sanitize_redirect(['myapp.com'], None), None)
def test_empty_redirect(self):
- self.assertEqual(sanitize_redirect('myapp.com', ''), None)
+ self.assertEqual(sanitize_redirect(['myapp.com'], ''), None)
def test_dict_redirect(self):
- self.assertEqual(sanitize_redirect('myapp.com', {}), None)
+ self.assertEqual(sanitize_redirect(['myapp.com'], {}), None)
def test_invalid_redirect(self):
- self.assertEqual(sanitize_redirect('myapp.com', {'foo': 'bar'}), None)
+ self.assertEqual(sanitize_redirect(['myapp.com'], {'foo': 'bar'}), None)
def test_wrong_path_redirect(self):
self.assertEqual(
- sanitize_redirect('myapp.com', 'http://notmyapp.com/path/'),
+ sanitize_redirect(['myapp.com'], 'http://notmyapp.com/path/'),
None
)
def test_valid_absolute_redirect(self):
self.assertEqual(
- sanitize_redirect('myapp.com', 'http://myapp.com/path/'),
+ sanitize_redirect(['myapp.com'], 'http://myapp.com/path/'),
'http://myapp.com/path/'
)
def test_valid_relative_redirect(self):
- self.assertEqual(sanitize_redirect('myapp.com', '/path/'), '/path/')
+ self.assertEqual(sanitize_redirect(['myapp.com'], '/path/'), '/path/')
+
+ def test_multiple_hosts(self):
+ allowed_hosts = ['myapp1.com', 'myapp2.com']
+ for host in allowed_hosts:
+ url = 'http://{}/path/'.format(host)
+ self.assertEqual(sanitize_redirect(allowed_hosts, url), url)
+
+ def test_multiple_hosts_wrong_host(self):
+ self.assertEqual(sanitize_redirect(
+ ['myapp1.com', 'myapp2.com'], 'http://notmyapp.com/path/'), None)
class UserIsAuthenticatedTest(unittest.TestCase):
diff --git a/social/utils.py b/social/utils.py
index 0b5a507..c70db52 100644
--- a/social/utils.py
+++ b/social/utils.py
@@ -81,21 +81,21 @@ def setting_name(*names):
return to_setting_name(*((SETTING_PREFIX,) + names))
-def sanitize_redirect(host, redirect_to):
+def sanitize_redirect(hosts, redirect_to):
"""
- Given the hostname and an untrusted URL to redirect to,
+ Given a list of hostnames and an untrusted URL to redirect to,
this method tests it to make sure it isn't garbage/harmful
and returns it, else returns None, similar as how's it done
on django.contrib.auth.views.
"""
if redirect_to:
try:
- # Don't redirect to a different host
- netloc = urlparse(redirect_to)[1] or host
+ # Don't redirect to a host not in a list
+ netloc = urlparse(redirect_to)[1] or hosts[0]
except (TypeError, AttributeError):
pass
else:
- if netloc == host:
+ if netloc in hosts:
return redirect_to
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-social-auth.git
More information about the Python-modules-commits
mailing list