Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
bug: enforce VAPID "aud" compliance.
Browse files Browse the repository at this point in the history
Closes: bug 1663922
  • Loading branch information
jrconlin committed Sep 10, 2020
1 parent 8287b52 commit 23bfeb8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
34 changes: 30 additions & 4 deletions autopush/tests/test_integration.py
Expand Up @@ -67,7 +67,7 @@ def setup_module():

def _get_vapid(key=None, payload=None):
if not payload:
payload = {"aud": "https://pusher_origin.example.com",
payload = {"aud": "http://localhost",
"exp": int(time.time()) + 86400,
"sub": "mailto:admin@example.com"}
if not key:
Expand Down Expand Up @@ -781,7 +781,7 @@ def test_basic_delivery_with_invalid_vapid_exp(self):
data = str(uuid.uuid4())
client = yield self.quick_register()
vapid_info = _get_vapid(
payload={"aud": "https://pusher_origin.example.com",
payload={"aud": "http://localhost",
"exp": '@',
"sub": "mailto:admin@example.com"})
yield client.send_notification(
Expand All @@ -790,7 +790,7 @@ def test_basic_delivery_with_invalid_vapid_exp(self):
status=401)

vapid_info = _get_vapid(
payload={"aud": "https://pusher_origin.example.com",
payload={"aud": "http://localhost",
"exp": ['@'],
"sub": "mailto:admin@example.com"})
yield client.send_notification(
Expand All @@ -799,6 +799,30 @@ def test_basic_delivery_with_invalid_vapid_exp(self):
status=401)
yield self.shut_down(client)

@inlineCallbacks
def test_basic_delivery_with_invalid_vapid_aud(self):
data = str(uuid.uuid4())
client = yield self.quick_register()
# try a different domain.
vapid_info = _get_vapid(
payload={"aud": "http://127.0.0.1",
"sub": "mailto:admin@example.com"})
yield client.send_notification(
data=data,
vapid=vapid_info,
status=401)

# try a different scheme
vapid_info = _get_vapid(
payload={"aud": "https://localhost",
"sub": "mailto:admin@example.com"})
yield client.send_notification(
data=data,
vapid=vapid_info,
status=401)
yield self.shut_down(client)


@inlineCallbacks
def test_basic_delivery_with_invalid_vapid_auth(self):
data = str(uuid.uuid4())
Expand Down Expand Up @@ -1522,7 +1546,7 @@ def test_webpush_monthly_rotation_no_channels(self):
@inlineCallbacks
def test_with_key(self):
private_key = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p)
claims = {"aud": "http://example.com",
claims = {"aud": "http://localhost",
"exp": int(time.time()) + 86400,
"sub": "a@example.com"}
vapid = _get_vapid(private_key, claims)
Expand Down Expand Up @@ -2065,6 +2089,8 @@ def _add_router(self):
"app_id": "amzn1.application.StringOfStuff",
"client_id": "amzn1.application-oa2-client.ev4nM0reStuff",
"client_secret": "deadbeef0000decafbad1111",
"hostname": "localhost",
"endpoint_scheme": "http",
}
},
self.ep.db.metrics,
Expand Down
9 changes: 5 additions & 4 deletions autopush/tests/test_web_validation.py
Expand Up @@ -626,6 +626,7 @@ def _make_fut(self):
from autopush.web.webpush import WebPushRequestSchema
conf = AutopushConfig(
hostname="localhost",
endpoint_scheme="http",
statsd_host=None,
)
db = test_db()
Expand Down Expand Up @@ -666,7 +667,7 @@ def test_valid_vapid_crypto_header(self):
schema = self._make_fut()

header = {"typ": "JWT", "alg": "ES256"}
payload = {"aud": "https://pusher_origin.example.com",
payload = {"aud": "http://localhost",
"exp": int(time.time()) + 86400,
"sub": "mailto:admin@example.com"}

Expand Down Expand Up @@ -698,7 +699,7 @@ def test_valid_vapid_crypto_header_webpush(self, use_crypto=False):
schema.context["conf"].use_cryptography = use_crypto

header = {"typ": "JWT", "alg": "ES256"}
payload = {"aud": "https://pusher_origin.example.com",
payload = {"aud": "http://localhost",
"exp": int(time.time()) + 86400,
"sub": "mailto:admin@example.com"}

Expand Down Expand Up @@ -732,7 +733,7 @@ def test_valid_vapid_02_crypto_header_webpush(self):
schema = self._make_fut()

header = {"typ": "JWT", "alg": "ES256"}
payload = {"aud": "https://pusher_origin.example.com",
payload = {"aud": "http://localhost",
"exp": int(time.time()) + 86400,
"sub": "mailto:admin@example.com"}

Expand Down Expand Up @@ -763,7 +764,7 @@ def test_valid_vapid_02_crypto_header_webpush_alt(self):
schema = self._make_fut()

header = {"typ": "JWT", "alg": "ES256"}
payload = {"aud": "https://pusher_origin.example.com",
payload = {"aud": "http://localhost",
"exp": int(time.time()) + 86400,
"sub": "mailto:admin@example.com"}

Expand Down
10 changes: 10 additions & 0 deletions autopush/web/webpush.py
Expand Up @@ -425,6 +425,16 @@ def validate_auth(self, d):
raise InvalidRequest("Invalid Authorization Header",
status_code=401, errno=109,
headers={"www-authenticate": PREF_SCHEME})
if "aud" not in jwt:
raise InvalidRequest("Invalid bearer token: No Audience specified",
status_code=401, errno=109,
headers={"www-authenticate": PREF_SCHEME})
if jwt['aud'] != "{}://{}".format(
self.context["conf"].endpoint_scheme or "http",
self.context["conf"].hostname):
raise InvalidRequest("Invalid bearer token: Invalid Audience Specified",
status_code=401, errno=109,
headers={"www-authenticate": PREF_SCHEME})
if "exp" not in jwt:
raise InvalidRequest("Invalid bearer token: No expiration",
status_code=401, errno=109,
Expand Down

0 comments on commit 23bfeb8

Please sign in to comment.