Skip to content

Commit 4f65d79

Browse files
authored
Merge pull request #335 from dinkom/stormpath-330
Custom URL in auth methods check
2 parents 2351419 + 02e98b8 commit 4f65d79

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

‎stormpath/api_auth.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ def authenticate(self, id_site_jwt, organization_name_key=None, account_store=No
539539
"""
540540
if not url:
541541
url = self.app.href + '/oauth/token'
542+
else:
543+
if not url.startswith(self.app._client.BASE_URL):
544+
raise ValueError('Invalid API url.')
542545

543546
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
544547
data = {
@@ -597,6 +600,9 @@ def authenticate(self, provider_id, code=None, access_token=None, account_store=
597600
"""
598601
if not url:
599602
url = self.app.href + '/oauth/token'
603+
else:
604+
if not url.startswith(self.app._client.BASE_URL):
605+
raise ValueError('Invalid API url.')
600606

601607
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
602608
data = {
@@ -661,6 +667,9 @@ def authenticate(self, username, password, account_store=None, url=None):
661667
"""
662668
if not url:
663669
url = self.app.href + '/oauth/token'
670+
else:
671+
if not url.startswith(self.app._client.BASE_URL):
672+
raise ValueError('Invalid API url.')
664673

665674
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
666675
data = {
@@ -701,6 +710,9 @@ class ClientCredentialsGrantAuthenticator(Authenticator):
701710
def authenticate(self, client_id, client_secret, account_store=None, url=None):
702711
if not url:
703712
url = self.app.href + '/oauth/token'
713+
else:
714+
if not url.startswith(self.app._client.BASE_URL):
715+
raise ValueError('Invalid API url.')
704716

705717
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
706718

‎tests/live/test_api_auth.py‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,50 @@ def test_authenticate_with_account_store_succeeds(self):
11171117
self.assertEqual(result.expires_in, 3600)
11181118
self.assertEqual(result.account.href, self.acc.href)
11191119

1120+
def test_with_invalid_url_fails(self):
1121+
id_site_url = self.app.build_id_site_redirect_url(
1122+
'https://hi.com')
1123+
1124+
resp = get(id_site_url, allow_redirects=False)
1125+
jwt = resp.headers['Location'].split('jwt=')[1]
1126+
origin = resp.headers['Location'].split('#')[0]
1127+
1128+
resp = get(self.app.href, params={'expand': 'idSiteModel'}, headers={
1129+
'Authorization': 'Bearer {}'.format(jwt),
1130+
'Origin': origin,
1131+
'Referer': origin,
1132+
})
1133+
1134+
next_jwt = resp.headers['Authorization'].split('Bearer ')[1]
1135+
1136+
post_url = '%s%s' % (self.app.href, '/loginAttempts')
1137+
headers = {
1138+
'Authorization': 'Bearer {}'.format(next_jwt),
1139+
'Origin': origin,
1140+
'Referer': origin,
1141+
'Content Type': 'application/json'
1142+
}
1143+
1144+
user_pass = '%s:%s' % (self.acc.email, self.password)
1145+
try:
1146+
encrypted_value = base64.b64encode(bytes(user_pass))
1147+
except TypeError:
1148+
# Python 3
1149+
encrypted_value = base64.b64encode(bytes(user_pass, 'utf-8'))
1150+
encrypted_value = encrypted_value.decode('utf-8')
1151+
1152+
body = {
1153+
'value': encrypted_value,
1154+
'type': 'basic'
1155+
}
1156+
resp = post(post_url, headers=headers, json=body)
1157+
final_jwt = resp.headers['stormpath-sso-redirect-location'].split('jwtResponse=')[1]
1158+
1159+
authenticator = StormpathTokenGrantAuthenticator(self.app)
1160+
1161+
with self.assertRaises(ValueError):
1162+
authenticator.authenticate(final_jwt, url='http://attack.com')
1163+
11201164

11211165
class TestStormpathSocialGrantAuthenticator(ApiKeyBase):
11221166
def setUp(self):
@@ -1251,6 +1295,15 @@ def test_authenticate_with_account_store_succeeds(self):
12511295
self.assertEqual(result.expires_in, 3600)
12521296
self.assertEqual(result.account.email, self.test_user['email'])
12531297

1298+
def test_with_invalid_url_fails(self):
1299+
authenticator = StormpathSocialGrantAuthenticator(self.app)
1300+
with self.assertRaises(ValueError):
1301+
authenticator.authenticate(
1302+
provider_id=Provider.FACEBOOK,
1303+
access_token=self.test_user['access_token'],
1304+
url='http://attack.com'
1305+
)
1306+
12541307

12551308
class TestPasswordGrantAuthenticator(ApiKeyBase):
12561309
def setUp(self):
@@ -1378,6 +1431,13 @@ def test_authenticate_with_account_store_org_href_succeeds(self):
13781431
self.assertEqual(result.account.href, self.acc.href)
13791432
self.assertEqual(claims.get('org'), self.org.href)
13801433

1434+
def test_with_invalid_url_fails(self):
1435+
authenticator = PasswordGrantAuthenticator(self.app)
1436+
with self.assertRaises(ValueError):
1437+
authenticator.authenticate(self.username,
1438+
self.password,
1439+
url='http://attack.com')
1440+
13811441

13821442
class TestClientCredentialsGrantAuthenticator(ApiKeyBase):
13831443

@@ -1450,6 +1510,13 @@ def test_authenticate_with_account_store_fails(self):
14501510

14511511
self.assertIsNone(result)
14521512

1513+
def test_with_invalid_url_fails(self):
1514+
authenticator = ClientCredentialsGrantAuthenticator(self.app)
1515+
with self.assertRaises(ValueError):
1516+
authenticator.authenticate(self.user_api_key.id,
1517+
self.user_api_key.secret,
1518+
url='http://attack.com')
1519+
14531520

14541521
class TestJwtAuthenticator(ApiKeyBase):
14551522
def setUp(self):

0 commit comments

Comments
 (0)