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

Commit

Permalink
bug: Prevent invalid header values from causing key errors in validation
Browse files Browse the repository at this point in the history
marshmallow may be more "helpful" than we'd like.

Closes #604
  • Loading branch information
jrconlin committed Aug 17, 2016
1 parent 7dc79e4 commit 55e08bf
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
15 changes: 15 additions & 0 deletions autopush/tests/test_web_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,21 @@ def test_valid_data(self):
ok_("message_id" in result)
eq_(str(result["subscription"]["uaid"]), dummy_uaid)

def test_no_headers(self):
schema = self._makeFUT()
schema.context["settings"].parse_endpoint.return_value = dict(
uaid=dummy_uaid,
chid=dummy_chid,
public_key="",
)
schema.context["settings"].router.get_uaid.return_value = dict(
router_type="webpush",
)
data = self._make_test_data(body="asdfasdf",
headers={"ttl": "invalid"})
result, errors = schema.load(data)
eq_(errors, {'headers': {'ttl': [u'Not a valid integer.']}})

def test_invalid_simplepush_user(self):
schema = self._makeFUT()
schema.context["settings"].parse_endpoint.return_value = dict(
Expand Down
33 changes: 17 additions & 16 deletions autopush/web/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def extract_subscription(self, d):
raise InvalidRequest("invalid token", errno=102)
return result

@validates_schema
@validates_schema(skip_on_field_errors=True)
def validate_uaid(self, d):
try:
result = self.context["settings"].router.get_uaid(d["uaid"].hex)
Expand Down Expand Up @@ -271,25 +271,26 @@ def validate_data(self, value):
errno=104,
)

@validates_schema
@validates_schema(skip_on_field_errors=True)
def ensure_encoding_with_data(self, d):
# This runs before nested schemas, so we use the - separated
# field name
req_fields = ["content-encoding", "encryption"]
if d["body"] and not all([x in d["headers"] for x in req_fields]):
raise InvalidRequest("Client error", errno=110)
if (d["headers"].get("crypto-key") and
"dh=" not in d["headers"]["crypto-key"]):
raise InvalidRequest(
"Crypto-Key header missing public-key 'dh' value",
status_code=401,
errno=110)
if (d["headers"].get("encryption") and
"salt=" not in d["headers"]["encryption"]):
raise InvalidRequest(
"Encryption header missing 'salt' value",
status_code=401,
errno=110)
if d.get("body"):
if not all([x in d["headers"] for x in req_fields]):
raise InvalidRequest("Client error", errno=110)
if (d["headers"].get("crypto-key") and
"dh=" not in d["headers"]["crypto-key"]):
raise InvalidRequest(
"Crypto-Key header missing public-key 'dh' value",
status_code=401,
errno=110)
if (d["headers"].get("encryption") and
"salt=" not in d["headers"]["encryption"]):
raise InvalidRequest(
"Encryption header missing 'salt' value",
status_code=401,
errno=110)

@pre_load
def token_prep(self, d):
Expand Down

0 comments on commit 55e08bf

Please sign in to comment.