#!/usr/bin/env python3 import os import sys import hmac import hashlib from datetime import datetime, timezone MAX_SKEW = 300 # secondes def main(): if len(sys.argv) != 4: print("INVALIDE: arguments manquants (attendu: timestamp signature raw_body)") return 1 timestamp, signature, body_arg = sys.argv[1:4] signature = signature.removeprefix("sha256=") secret = os.environ.get("WEBHOOK_SECRET", "") if not secret: print("INVALIDE: WEBHOOK_SECRET non défini") return 1 # 1. Fraîcheur du timestamp try: ts = datetime.fromisoformat(timestamp) if ts.tzinfo is None: ts = ts.replace(tzinfo=timezone.utc) except ValueError: print(f"INVALIDE: timestamp illisible ({timestamp})") return 1 skew = abs((datetime.now(timezone.utc) - ts).total_seconds()) if skew > MAX_SKEW: print(f"INVALIDE: timestamp trop ancien/futur ({skew:.0f}s d'écart)") return 1 # 2. Signature sur les octets bruts + timestamp # os.fsencode restitue les octets exacts reçus dans argv raw_body = os.fsencode(body_arg) expected = hmac.new( secret.encode("utf-8"), raw_body + timestamp.encode("utf-8"), hashlib.sha256, ).hexdigest() if not hmac.compare_digest(expected, signature): print("INVALIDE: signature incorrecte") return 1 print("VALIDE") return 0 if __name__ == "__main__": sys.exit(main())