Vebhuk imzosini HMAC orqali tekshirish va soxtalashtirishdan himoya
Amaliyot4 daqInnovialabs tahririyati
Qisqacha
So‘rovning xom tanasi (va timestamp) bo‘yicha HMAC ni umumiy sir bilan qayta hisoblang, imzo bilan doimiy vaqtda taqqoslang, eski timestamp va takroriy hodisa ID larini rad eting — va shundan keyingina vebhukka ishonib, uni qayta ishlang.
Qisqa javob
Vebhuk URL manzili ochiq: uni bilgan har kim «to‘lov o‘tdi» degan soxta so‘rov yuborishi mumkin. Imzo so‘rovni umumiy sirni biladigan tomon yuborganini va tana o‘zgartirilmaganini isbotlaydi. Uni tekshirish uchun:
- Xom tanani JSON parsing dan oldin, aynan kelgan holida o‘qing.
HMAC-SHA256(secret, timestamp + "." + body)ni yoki provayder hujjatlarida tasvirlangan satrni hisoblang.- Imzo sarlavhasi bilan doimiy vaqtli taqqoslash orqali solishtiring.
- Eski timestamp va allaqachon qayta ishlangan hodisa ID li so‘rovlarni rad eting.
- Faqat shundan keyin ma’lumotlarni parsing qiling va qayta ishlang.
HMAC qanday ishlaydi
HMAC — maxfiy kalit bilan birlashtirilgan xesh funksiya. Yuboruvchi va qabul qiluvchi sirni biladi; yuboruvchi xabarning HMAC ini hisoblab sarlavhaga qo‘yadi, qabul qiluvchi uni qayta hisoblaydi. Sirsiz hujumchi to‘g‘ri imzo yarata olmaydi, tanadagi har qanday o‘zgarish esa natijani o‘zgartiradi.
HMAC shifrlash emas: tana o‘qiladigan bo‘lib qoladi, shuning uchun vebhuklar HTTPS orqali yuborilishi kerak.
Kod misoli: Node.js
import crypto from "node:crypto";
export function verifyWebhook(rawBody, timestamp, signature, secret) {
const age = Math.abs(Date.now() / 1000 - Number(timestamp));
if (!Number.isFinite(age) || age > 300) return false; // 5 daqiqalik oyna
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(String(signature), "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Express da vebhuk marshrutida tanani express.raw({ type: "application/json" }) orqali o‘qing: parsing qilingan JSON ni qayta seriyalash bo‘shliqlar yoki kalitlar tartibini o‘zgartirib, imzoni buzishi mumkin.
Kod misoli: Python
import hashlib
import hmac
import time
def verify_webhook(raw_body: bytes, timestamp: str, signature: str, secret: bytes) -> bool:
if abs(time.time() - int(timestamp)) > 300:
return False
message = timestamp.encode() + b"." + raw_body
expected = hmac.new(secret, message, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
Doimiy vaqtli taqqoslash nima uchun kerak
Oddiy == birinchi mos kelmagan belgida to‘xtaydi. Javob vaqtini o‘lchab, hujumchi nazariy jihatdan imzoni bayt-baytlab topishi mumkin. crypto.timingSafeEqual va hmac.compare_digest satrlar qayerda farqlanishidan qat’i nazar bir xil vaqt ishlaydi.
Qayta yuborishdan (replay) himoya
To‘g‘ri imzolangan so‘rovni ushlab olib, qayta yuborish mumkin. Ikki himoya birgalikda ishlaydi:
- Imzolanadigan satr ichidagi timestamp: qisqa oynadan tashqaridagi so‘rovlarni rad eting. Timestamp albatta HMAC ga kirishi kerak, aks holda uni shunchaki almashtirishadi.
- Hodisa ID bo‘yicha idempotentlik: qayta ishlangan hodisa yoki tranzaksiya ID larini saqlang va takrorlarni e’tiborsiz qoldiring. Provayderlarning o‘zi ham vebhuklarni qonuniy ravishda takrorlaydi, shuning uchun bu ikki marta hisoblashdan ham himoya qiladi.
IP allowlist
Ba’zi provayderlar kolbeklar keladigan manzillarni e’lon qiladi. Allowlist foydali qo‘shimcha qatlam, lekin imzo o‘rnini bosmaydi:
- IP ro‘yxatlari o‘zgaradi, ularni kodda emas, konfigda saqlang;
- proksi yoki balanslovchi ortida mijoz IP sini faqat o‘zingizning proksi qo‘yadigan sarlavhadan oling, aks holda uni soxtalashtirishadi.
Sirni almashtirish (rotatsiya)
- Sirni sirlar menejerida yoki muhit o‘zgaruvchilarida saqlang, hech qachon repozitoriyda emas.
- Rotatsiya paytida ikkita faol sirni qo‘llab-quvvatlang: istalgani bo‘yicha to‘g‘ri imzoni qabul qiling, keyin eskisini o‘chiring.
- Sir sizib chiqqan bo‘lishi mumkin bo‘lsa, masalan kirish huquqi bor xodim ketganda, uni darhol almashtiring.
- Har bir muhit va har bir integratsiya uchun alohida sir.
Payme va Click
Mahalliy to‘lov tizimlari har doim ham klassik HMAC dan foydalanmaydi, shuning uchun ularning hujjatlariga qat’iy amal qiling:
- Payme Merchant API endpointingizni HTTP Basic autentifikatsiya bilan chaqiradi, bunda parol sifatida kabinetdagi merchant kaliti ishlatiladi. Har bir so‘rovda
Authorizationsarlavhasini doimiy vaqtli taqqoslash bilan tekshiring va mos kelmasa, protokolda belgilangan xatoni qaytaring. Manba IP sini tekshirish — ikkinchi qatlam. - Click SHOP API
sign_stringyuboradi — so‘rov maydonlari sizning maxfiy kalitingiz bilan birlashtirilgan MD5 xeshi. Satrni hujjatdagi maydonlar tartibida yig‘ing, xeshlang va solishtiring. Prepare va Complete so‘rovlarida maydonlar to‘plami farq qiladi.
Ikkala holatda ham qo‘shimcha ravishda summa va buyurtma ID sini o‘z bazangiz bilan solishtiring va qayta ishlashni idempotent qiling: to‘g‘ri imzo summa buyurtmaga mos kelishini anglatmaydi.
Ko‘p uchraydigan xatolar
- Imzoni JSON parsing va qayta seriyalashdan keyin tekshirish.
- So‘rovni sarlavhalari, jumladan imzo yoki Basic ma’lumotlari bilan to‘liq loglash.
- Hujumchiga qaysi tekshiruv o‘tmaganini bildiradigan batafsil xatolar.
- Summa va holatni tekshirmasdan vebhukni to‘lov isboti deb hisoblash.