providers/oauth2: improve error handling for invalid regular expressions

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-05-23 20:47:36 +02:00
parent 6460245d5e
commit 8c9748e4a0
3 changed files with 44 additions and 12 deletions

View file

@ -78,6 +78,28 @@ class TestAuthorize(OAuthTestCase):
) )
OAuthAuthorizationParams.from_request(request) OAuthAuthorizationParams.from_request(request)
def test_invalid_redirect_uri_regex(self):
"""test missing/invalid redirect URI"""
OAuth2Provider.objects.create(
name="test",
client_id="test",
authorization_flow=create_test_flow(),
redirect_uris="*",
)
with self.assertRaises(RedirectUriError):
request = self.factory.get("/", data={"response_type": "code", "client_id": "test"})
OAuthAuthorizationParams.from_request(request)
with self.assertRaises(RedirectUriError):
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "http://localhost",
},
)
OAuthAuthorizationParams.from_request(request)
def test_empty_redirect_uri(self): def test_empty_redirect_uri(self):
"""test empty redirect URI (configure in provider)""" """test empty redirect URI (configure in provider)"""
OAuth2Provider.objects.create( OAuth2Provider.objects.create(

View file

@ -1,6 +1,7 @@
"""authentik OAuth2 Authorization views""" """authentik OAuth2 Authorization views"""
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import timedelta from datetime import timedelta
from re import error as RegexError
from re import fullmatch from re import fullmatch
from typing import Optional from typing import Optional
from urllib.parse import parse_qs, urlencode, urlparse, urlsplit, urlunsplit from urllib.parse import parse_qs, urlencode, urlparse, urlsplit, urlunsplit
@ -184,12 +185,16 @@ class OAuthAuthorizationParams:
self.provider.save() self.provider.save()
allowed_redirect_urls = self.provider.redirect_uris.split() allowed_redirect_urls = self.provider.redirect_uris.split()
if not any(fullmatch(x, self.redirect_uri) for x in allowed_redirect_urls): try:
LOGGER.warning( if not any(fullmatch(x, self.redirect_uri) for x in allowed_redirect_urls):
"Invalid redirect uri", LOGGER.warning(
redirect_uri=self.redirect_uri, "Invalid redirect uri",
excepted=allowed_redirect_urls, redirect_uri=self.redirect_uri,
) excepted=allowed_redirect_urls,
)
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
except RegexError as exc:
LOGGER.warning("Invalid regular expression configured", exc=exc)
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls) raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
if self.request: if self.request:
raise AuthorizeError( raise AuthorizeError(

View file

@ -2,6 +2,7 @@
from base64 import urlsafe_b64encode from base64 import urlsafe_b64encode
from dataclasses import InitVar, dataclass from dataclasses import InitVar, dataclass
from hashlib import sha256 from hashlib import sha256
from re import error as RegexError
from re import fullmatch from re import fullmatch
from typing import Any, Optional from typing import Any, Optional
@ -149,12 +150,16 @@ class TokenParams:
allowed_redirect_urls = self.provider.redirect_uris.split() allowed_redirect_urls = self.provider.redirect_uris.split()
# At this point, no provider should have a blank redirect_uri, in case they do # At this point, no provider should have a blank redirect_uri, in case they do
# this will check an empty array and raise an error # this will check an empty array and raise an error
if not any(fullmatch(x, self.redirect_uri) for x in allowed_redirect_urls): try:
LOGGER.warning( if not any(fullmatch(x, self.redirect_uri) for x in allowed_redirect_urls):
"Invalid redirect uri", LOGGER.warning(
redirect_uri=self.redirect_uri, "Invalid redirect uri",
excepted=allowed_redirect_urls, redirect_uri=self.redirect_uri,
) excepted=allowed_redirect_urls,
)
raise TokenError("invalid_client")
except RegexError as exc:
LOGGER.warning("Invalid regular expression configured", exc=exc)
raise TokenError("invalid_client") raise TokenError("invalid_client")
try: try: