Commit 5f6d25dd authored by Sofia Papagiannaki's avatar Sofia Papagiannaki
Browse files

astakos oa2: Set a redirect URI length limit.

This limit is configurable and is applied in the api level.

Refs: #4804
parent 31177b99
......@@ -253,7 +253,8 @@ class SimpleBackend(object):
def __init__(self, base_url='', endpoints_prefix='oauth2/', id='oauth2',
token_endpoint='token/', token_length=30,
token_expires=20, authorization_endpoint='auth/',
authorization_code_length=60, **kwargs):
authorization_code_length=60,
redirect_uri_limit=5000, **kwargs):
self.base_url = base_url
self.endpoints_prefix = endpoints_prefix
self.token_endpoint = token_endpoint
......@@ -263,6 +264,7 @@ class SimpleBackend(object):
self.authorization_code_length = authorization_code_length
self.id = id
self._errors_to_http = kwargs.get('errors_to_http', True)
self.redirect_uri_limit = redirect_uri_limit
# Request/response builders
def build_request(self, method, get, post, meta):
......@@ -548,6 +550,8 @@ class SimpleBackend(object):
if redirect_uri is not None:
if not bool(urlparse.urlparse(redirect_uri).scheme):
raise OA2Error("Redirect uri should be an absolute URI")
if len(redirect_uri) > self.redirect_uri_limit:
raise OA2Error("Redirect uri length limit exceeded")
if not client.redirect_uri_is_valid(redirect_uri):
raise OA2Error("Mismatching redirect uri")
if expected_value is not None and redirect_uri != expected_value:
......
......@@ -20,3 +20,8 @@ TOKEN_LENGTH = get_setting('TOKEN_LENGTH', 30)
# Set the expiration time of newly created access tokens to 20 seconds
TOKEN_EXPIRES = get_setting('TOKEN_EXPIRES', 20)
# Set the maximum allowed redirection endpoint URI length
# Requests for a greater redirection endpoint URI will fail.
MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH = get_setting(
'MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH', 5000)
......@@ -315,27 +315,27 @@ class TestOA2(TestCase, URLAssertionsMixin):
self.assertCount(AuthorizationCode, 1)
# redirect is valid
redirect1 = self.get_redirect_url(r)
self.assertParam(redirect1, "code")
self.assertNoParam(redirect1, "extra_param")
self.assertHost(redirect1, "server.com")
self.assertPath(redirect1, "/handle_code")
redirect = self.get_redirect_url(r)
self.assertParam(redirect, "code")
self.assertNoParam(redirect, "extra_param")
self.assertHost(redirect, "server.com")
self.assertPath(redirect, "/handle_code")
code = AuthorizationCode.objects.get(code=redirect.params['code'][0])
#self.assertEqual(code.state, '')
self.assertEqual(code.state, None)
self.assertEqual(code.redirect_uri, self.client1_redirect_uri)
params['state'] = 'csrfstate'
params['scope'] = 'resource1'
r = self.client.authorize_code('client1', urlparams=params)
redirect2 = self.get_redirect_url(r)
self.assertParamEqual(redirect2, "state", 'csrfstate')
redirect = self.get_redirect_url(r)
self.assertParamEqual(redirect, "state", 'csrfstate')
self.assertCount(AuthorizationCode, 2)
code1 = AuthorizationCode.objects.get(code=redirect1.params['code'][0])
#self.assertEqual(code1.state, '')
self.assertEqual(code1.state, None)
self.assertEqual(code1.redirect_uri, self.client1_redirect_uri)
code2 = AuthorizationCode.objects.get(code=redirect2.params['code'][0])
self.assertEqual(code2.state, 'csrfstate')
self.assertEqual(code2.redirect_uri, self.client1_redirect_uri)
code = AuthorizationCode.objects.get(code=redirect.params['code'][0])
self.assertEqual(code.state, 'csrfstate')
self.assertEqual(code.redirect_uri, self.client1_redirect_uri)
# valid request: trusted client
params = {'redirect_uri': self.client3_redirect_uri,
......@@ -347,16 +347,16 @@ class TestOA2(TestCase, URLAssertionsMixin):
self.assertCount(AuthorizationCode, 3)
# redirect is valid
redirect3 = self.get_redirect_url(r)
self.assertParam(redirect1, "code")
self.assertNoParam(redirect3, "state")
self.assertNoParam(redirect3, "extra_param")
self.assertHost(redirect3, "server3.com")
self.assertPath(redirect3, "/handle_code")
redirect = self.get_redirect_url(r)
self.assertParam(redirect, "code")
self.assertNoParam(redirect, "state")
self.assertNoParam(redirect, "extra_param")
self.assertHost(redirect, "server3.com")
self.assertPath(redirect, "/handle_code")
code3 = AuthorizationCode.objects.get(code=redirect3.params['code'][0])
self.assertEqual(code3.state, None)
self.assertEqual(code3.redirect_uri, self.client3_redirect_uri)
code = AuthorizationCode.objects.get(code=redirect.params['code'][0])
self.assertEqual(code.state, None)
self.assertEqual(code.redirect_uri, self.client3_redirect_uri)
# valid request: trusted client
params['state'] = 'csrfstate'
......@@ -366,16 +366,16 @@ class TestOA2(TestCase, URLAssertionsMixin):
self.assertCount(AuthorizationCode, 4)
# redirect is valid
redirect4 = self.get_redirect_url(r)
self.assertParam(redirect4, "code")
self.assertParamEqual(redirect4, "state", 'csrfstate')
self.assertNoParam(redirect4, "extra_param")
self.assertHost(redirect4, "server3.com")
self.assertPath(redirect4, "/handle_code")
redirect = self.get_redirect_url(r)
self.assertParam(redirect, "code")
self.assertParamEqual(redirect, "state", 'csrfstate')
self.assertNoParam(redirect, "extra_param")
self.assertHost(redirect, "server3.com")
self.assertPath(redirect, "/handle_code")
code4 = AuthorizationCode.objects.get(code=redirect4.params['code'][0])
self.assertEqual(code4.state, 'csrfstate')
self.assertEqual(code4.redirect_uri, self.client3_redirect_uri)
code = AuthorizationCode.objects.get(code=redirect.params['code'][0])
self.assertEqual(code.state, 'csrfstate')
self.assertEqual(code.redirect_uri, self.client3_redirect_uri)
# redirect uri startswith the client's registered redirect url
params['redirect_uri'] = '%smore' % self.client3_redirect_uri
......@@ -392,37 +392,24 @@ class TestOA2(TestCase, URLAssertionsMixin):
self.assertCount(AuthorizationCode, 5)
# redirect is valid
redirect5 = self.get_redirect_url(r)
self.assertParam(redirect5, "code")
self.assertParamEqual(redirect5, "state", 'csrfstate')
self.assertNoParam(redirect5, "extra_param")
self.assertHost(redirect5, "server3.com")
self.assertPath(redirect5, urlparse.urlparse(redirect_uri).path)
code5 = AuthorizationCode.objects.get(code=redirect5.params['code'][0])
self.assertEqual(code5.state, 'csrfstate')
self.assertEqual(code5.redirect_uri,
redirect = self.get_redirect_url(r)
self.assertParam(redirect, "code")
self.assertParamEqual(redirect, "state", 'csrfstate')
self.assertNoParam(redirect, "extra_param")
self.assertHost(redirect, "server3.com")
self.assertPath(redirect, urlparse.urlparse(redirect_uri).path)
code = AuthorizationCode.objects.get(code=redirect.params['code'][0])
self.assertEqual(code.state, 'csrfstate')
self.assertEqual(code.redirect_uri,
'%s/more' % self.client3_redirect_uri)
# too long redirect uri
redirect_uri = '%s/%s' % (self.client3_redirect_uri, 'a'*2000)
redirect_uri = '%s?foo=%s' % (self.client3_redirect_uri, 'a'*10000)
params['redirect_uri'] = redirect_uri
self.client.set_credentials('client3', 'secret')
r = self.client.authorize_code('client3', urlparams=params)
self.assertEqual(r.status_code, 302)
self.assertCount(AuthorizationCode, 6)
# redirect is valid
redirect6 = self.get_redirect_url(r)
self.assertParam(redirect6, "code")
self.assertParamEqual(redirect6, "state", 'csrfstate')
self.assertNoParam(redirect6, "extra_param")
self.assertHost(redirect6, "server3.com")
self.assertPath(redirect6, urlparse.urlparse(redirect_uri).path)
code6 = AuthorizationCode.objects.get(code=redirect6.params['code'][0])
self.assertEqual(code6.state, 'csrfstate')
self.assertEqual(code6.redirect_uri, redirect_uri)
self.assertEqual(r.status_code, 400)
def test_get_token(self):
# invalid method
......
......@@ -42,5 +42,7 @@ oa2_backend = DjangoBackend(endpoints_prefix=settings.ENDPOINT_PREFIX,
authorization_endpoint=
settings.AUTHORIZATION_ENDPOINT,
authorization_code_length=
settings.AUTHORIZATION_CODE_LENGTH)
settings.AUTHORIZATION_CODE_LENGTH,
redirect_uri_limit=
settings.MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH)
urlpatterns = oa2_backend.get_url_patterns()
......@@ -14,3 +14,8 @@
#
## Set the expiration time of newly created access tokens to 20 seconds
#OAUTH2_TOKEN_EXPIRES = 20
#
# Set the maximum allowed redirection endpoint URI length
# Requests for a greater redirection endpoint URI will fail.
#OAUTH2_MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH = get_setting(
# 'MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH', 5000)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment