-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest_webhook_validator.py
More file actions
103 lines (73 loc) · 3.19 KB
/
test_webhook_validator.py
File metadata and controls
103 lines (73 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from faker import Faker
from urlbox import webhook_validator
from urlbox import InvalidHeaderSignatureError
import datetime
import json
import hmac
import pytest
from hashlib import sha256
fake = Faker()
timestamp_one_minute_ago = int(
datetime.datetime.timestamp(
datetime.datetime.now() - datetime.timedelta(minutes=1)
)
)
webhook_secret = fake.pystr()
header_signature = f"t={timestamp_one_minute_ago},sha256=1e1b3c7f6b5f60f7b44ed1a85e653769ecf0c41ec5c7e8c131fc1a20357cc2b1"
payload = {
"event": "render.succeeded",
"renderId": "794383cd-b09e-4aef-a12b-fadf8aad9d63",
"result": {
"renderUrl": "https://renders.urlbox.com/urlbox1/renders/61431b47b8538a00086c29dd/2021/11/24/bee42850-bab6-43c6-bd9d-e614581d31b4.png"
},
"meta": {
"startTime": "2021-11-24T16:49:48.307Z",
"endTime": "2021-11-24T16:49:53.659Z",
},
}
def test_call_valid_webhook():
# Dynamically generate header signature to make the crypto comparision pass
payload_json_string = json.dumps(payload, separators=(",", ":"))
signature_generated = hmac.new(
webhook_secret.encode("utf-8"),
msg=f"{timestamp_one_minute_ago}.{payload_json_string}".encode(
"utf-8"
),
digestmod=sha256,
).hexdigest()
header_signature = (
f"t={timestamp_one_minute_ago},sha256={signature_generated}"
)
assert (
webhook_validator.call(header_signature, payload, webhook_secret)
is True
)
def test_call_invalid_signature():
header_signature = fake.pystr()
with pytest.raises(InvalidHeaderSignatureError) as exception:
webhook_validator.call(header_signature, payload, webhook_secret)
def test_call_invalid_hash_mismatch():
header_signature = f"t={timestamp_one_minute_ago},sha256=930ee08957512f247e289703ac951fc60da1e2d12919bfd518d90513b0687ee0"
with pytest.raises(InvalidHeaderSignatureError) as exception:
webhook_validator.call(header_signature, payload, webhook_secret)
assert "Invalid signature" in str(exception.value)
def test_call_invalid_hash_regex_catch():
header_signature = f"t={timestamp_one_minute_ago},sha256={fake.pystr()}"
with pytest.raises(InvalidHeaderSignatureError) as exception:
webhook_validator.call(header_signature, payload, webhook_secret)
assert "Invalid signature" in str(exception.value)
def test_call_invalid_timestamp():
header_signature = f"t={fake.pystr()},sha256=930ee08957512f247e289703ac951fc60da1e2d12919bfd518d90513b0687ee0"
with pytest.raises(Exception) as exception:
webhook_validator.call(header_signature, payload, webhook_secret)
assert "Invalid timestamp" in str(exception.value)
def test_call_invalid_timestamp_timing_attack():
timestamp_ten_minute_ago = int(
datetime.datetime.timestamp(
datetime.datetime.now() - datetime.timedelta(minutes=10)
)
)
header_signature = f"t={timestamp_ten_minute_ago},sha256=930ee08957512f247e289703ac951fc60da1e2d12919bfd518d90513b0687ee0"
with pytest.raises(InvalidHeaderSignatureError) as exception:
webhook_validator.call(header_signature, payload, webhook_secret)
assert "Invalid timestamp" in str(exception.value)