पाठ 15 / 27
Webhooks: Signing और Verifying
बाहर जाने वाली events पर हस्ताक्षर करें और प्राप्ति पर जाँचें, replays रोकने को timestamp के साथ।
आपके URL पर कोई भी POST कर सकता है
Webhook वह HTTP callback है जो घटना होने पर आपका API उपभोक्ता के URL पर करता है। चूँकि उपभोक्ता का endpoint सार्वजनिक है, उसे भेजने वाले की पुष्टि कर पाना ज़रूरी है। मानक तरीक़ा: साझा secret से HMAC-SHA256 द्वारा request body पर हस्ताक्षर करें, और signature (तथा timestamp) header में भेजें। प्राप्तकर्ता body के कच्चे bytes पर HMAC दोबारा निकालता है, constant-time function से तुलना करता है, और replay attacks रोकने को कुछ मिनट से पुराने timestamps अस्वीकार करता है। Webhook भेजने वालों को विफल deliveries backoff के साथ retry करनी चाहिए, अनोखा event ID देना चाहिए ताकि प्राप्तकर्ता दोहराव हटा सकें, और उपभोक्ताओं को secrets बदलने देना चाहिए। प्राप्तकर्ताओं को जल्दी 2xx देना और event को asynchronously प्रोसेस करना चाहिए।
Signing और verifying, चलाकर
मैंने यह सादा-Python उदाहरण चलाया। Signature 64 अक्षरों का hex digest है। समय-सीमा के भीतर अछूती body ok सत्यापित होती है; एक अतिरिक्त byte वाली body ग़लत signature के रूप में अस्वीकार होती है; वही वैध संदेश 4,000 सेकंड बाद बहुत पुराना मानकर अस्वीकार होता है।
import hmac, hashlib, json, time, bisect
SECRET = b"whsec_demo"
def sign(body: bytes, ts: int) -> str:
return hmac.new(SECRET, f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
def verify(body, ts, sig, now, tolerance=300):
if abs(now - ts) > tolerance: return "rejected: too old"
return "ok" if hmac.compare_digest(sign(body, ts), sig) else "rejected: bad signature"
body = b'{"event":"payment.succeeded","id":"pay_1"}'; ts = 1_700_000_000
sig = sign(body, ts)
print(len(sig), verify(body, ts, sig, ts + 10), verify(body + b" ", ts, sig, ts + 10), verify(body, ts, sig, ts + 4000))
Output:
64 ok rejected: bad signature rejected: too old
कच्ची body जाँचें
Parse किए JSON को दोबारा serialise करने से whitespace और key क्रम बदलते हैं और signature टूटता है। मिले हुए ठीक bytes पर HMAC निकालें।
त्वरित जाँच: हस्ताक्षरित डेटा में timestamp क्यों शामिल करें?
- पुराने, दोहराए संदेश अस्वीकार करने के लिए
- Body छोटी करने के लिए
- क्योंकि HMAC को तारीख़ें चाहिए
- Delivery तेज़ करने के लिए
Answer
पुराने, दोहराए संदेश अस्वीकार करने के लिए — ताज़गी के बिना हमलावर पकड़ा हुआ वैध संदेश बाद में दोबारा भेज सकता है।