Utoljára aktív 1 week ago

remi's Avatar remi gist felülvizsgálása 1 week ago. Revízióhoz ugrás

Nincsenek változtatások

remi's Avatar remi gist felülvizsgálása 1 week ago. Revízióhoz ugrás

2 files changed, 88 insertions

hooks.yaml(fájl létrehozva)

@@ -0,0 +1,33 @@
1 + - id: debug
2 + execute-command: /usr/local/bin/log-hook.sh
3 + include-command-output-in-response: true
4 + pass-arguments-to-command:
5 + - source: entire-headers
6 + - source: raw-request-body
7 + - id: liberaforms
8 + execute-command: /usr/local/bin/verify-hook.py
9 + include-command-output-in-response: true
10 + pass-arguments-to-command:
11 + - source: header
12 + name: X-Timestamp
13 + - source: header
14 + name: X-Signature-256
15 + - source: raw-request-body
16 + pass-environment-to-command:
17 + - source: string
18 + name: foobar
19 + envname: WEBHOOK_SECRET
20 + trigger-rule:
21 + and:
22 + - match:
23 + type: regex
24 + regex: '^[0-9a-f]{64}$'
25 + parameter:
26 + source: header
27 + name: X-Signature-256
28 + - match:
29 + type: regex
30 + regex: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,6})?(Z|[+-]\d{2}:\d{2})$'
31 + parameter:
32 + source: header
33 + name: X-Timestamp

verify-hook.py(fájl létrehozva)

@@ -0,0 +1,55 @@
1 + #!/usr/bin/env python3
2 + import os
3 + import sys
4 + import hmac
5 + import hashlib
6 + from datetime import datetime, timezone
7 +
8 + MAX_SKEW = 300 # secondes
9 +
10 + def main():
11 + if len(sys.argv) != 4:
12 + print("INVALIDE: arguments manquants (attendu: timestamp signature raw_body)")
13 + return 1
14 +
15 + timestamp, signature, body_arg = sys.argv[1:4]
16 + signature = signature.removeprefix("sha256=")
17 +
18 + secret = os.environ.get("WEBHOOK_SECRET", "")
19 + if not secret:
20 + print("INVALIDE: WEBHOOK_SECRET non défini")
21 + return 1
22 +
23 + # 1. Fraîcheur du timestamp
24 + try:
25 + ts = datetime.fromisoformat(timestamp)
26 + if ts.tzinfo is None:
27 + ts = ts.replace(tzinfo=timezone.utc)
28 + except ValueError:
29 + print(f"INVALIDE: timestamp illisible ({timestamp})")
30 + return 1
31 +
32 + skew = abs((datetime.now(timezone.utc) - ts).total_seconds())
33 + if skew > MAX_SKEW:
34 + print(f"INVALIDE: timestamp trop ancien/futur ({skew:.0f}s d'écart)")
35 + return 1
36 +
37 + # 2. Signature sur les octets bruts + timestamp
38 + # os.fsencode restitue les octets exacts reçus dans argv
39 + raw_body = os.fsencode(body_arg)
40 +
41 + expected = hmac.new(
42 + secret.encode("utf-8"),
43 + raw_body + timestamp.encode("utf-8"),
44 + hashlib.sha256,
45 + ).hexdigest()
46 +
47 + if not hmac.compare_digest(expected, signature):
48 + print("INVALIDE: signature incorrecte")
49 + return 1
50 +
51 + print("VALIDE")
52 + return 0
53 +
54 + if __name__ == "__main__":
55 + sys.exit(main())
Újabb Régebbi