From e1c6f2a3c5bae53998bcd18db253691a90817421 Mon Sep 17 00:00:00 2001 From: Phil Booth Date: Fri, 13 May 2016 16:20:53 +0100 Subject: [PATCH] feat(server): reject assertions if fxa-tokenVerified is false --- tokenserver/tests/test_service.py | 20 ++++++++++++++++++++ tokenserver/views.py | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/tokenserver/tests/test_service.py b/tokenserver/tests/test_service.py index ba63a5b3..c18152b4 100644 --- a/tokenserver/tests/test_service.py +++ b/tokenserver/tests/test_service.py @@ -163,6 +163,26 @@ def test_unauthorized_error_status(self): with self.assertRaises(ValueError): res = self.app.get('/1.0/sync/1.1', headers=headers) + def test_unverified_token(self): + headers = {'Authorization': 'BrowserID %s' % self._getassertion()} + # Assertion should not be rejected if fxa-tokenVerified is unset + mock_response = { + "status": "okay", + "email": "test@mozilla.com", + "idpClaims": {} + } + with self.mock_verifier(response=mock_response): + self.app.get("/1.0/sync/1.1", headers=headers, status=200) + # Assertion should not be rejected if fxa-tokenVerified is True + mock_response['idpClaims']['fxa-tokenVerified'] = True + with self.mock_verifier(response=mock_response): + self.app.get("/1.0/sync/1.1", headers=headers, status=200) + # Assertion should be rejected if fxa-tokenVerified is False + mock_response['idpClaims']['fxa-tokenVerified'] = False + with self.mock_verifier(response=mock_response): + res = self.app.get("/1.0/sync/1.1", headers=headers, status=401) + self.assertEqual(res.json['status'], 'invalid-credentials') + def test_generation_number_change(self): headers = {"Authorization": "BrowserID %s" % self._getassertion()} # Start with no generation number. diff --git a/tokenserver/views.py b/tokenserver/views.py index e164b8b1..13857657 100644 --- a/tokenserver/views.py +++ b/tokenserver/views.py @@ -96,6 +96,15 @@ def valid_assertion(request): raise _unauthorized("invalid-timestamp") raise _unauthorized("invalid-credentials") + # FxA sign-in confirmation introduced the notion of unverified tokens. + # The default value is True to preserve backwards compatibility. + try: + tokenVerified = assertion['idpClaims']['fxa-tokenVerified'] + except KeyError: + tokenVerified = True + if not tokenVerified: + raise _unauthorized("invalid-credentials") + # everything sounds good, add the assertion to the list of validated fields # and continue request.metrics['token.assertion.verify_success'] = 1