İmza Doğrulama
HMAC-SHA256 imzaları kullanarak webhook teslimatlarının gerçekten YAPL'dan geldiğini doğrulayın.
Webhook İmzalarını Doğrulama
YAPL'dan gelen her webhook teslimatı, alıcı servisinizin isteğin gerçek olduğunu ve değiştirilmediğini doğrulayabilmesi için bir kriptografik imza içerir. Bu, saldırganların uç noktanıza sahte webhook yükleri göndermesini önler.
Nasıl Çalışır
- Bir webhook oluşturduğunuzda YAPL benzersiz bir imzalama sırrı üretir
- Her teslimat için YAPL, sırrınızı ve yükü kullanarak bir HMAC-SHA256 imzası hesaplar
- İmza,
X-YAPL-Signature-256istek başlığına eklenir - Servisiniz aynı sırrı kullanarak imzayı yeniden hesaplar ve karşılaştırır
İmzalar eşleşirse teslimat gerçektir.
Teslimat Başlıkları
Her webhook teslimatı şu başlıkları içerir:
| Başlık | Açıklama | Örnek |
|---|---|---|
X-YAPL-Signature-256 | HMAC-SHA256 imzası | sha256=a1b2c3d4... |
X-YAPL-Event | Olay türü | project.created.v1 |
X-YAPL-Delivery-ID | Benzersiz teslimat tanımlayıcısı | del_abc123 |
X-YAPL-Timestamp | İmzanın oluşturulduğu zaman (ISO 8601) | 2026-03-25T10:30:00.000Z |
İmza Hesaplama
İmza, zaman damgası ile ham JSON gövdesinin birleşmesi üzerinden hesaplanır:
imzalanabilir_yük = zaman_damgası + "." + ham_json_gövde
imza = "sha256=" + HMAC-SHA256(sır, imzalanabilir_yük)Zaman damgası, tekrar saldırılarını önlemek için dahil edilmiştir — bir saldırgan geçerli bir teslimatı yakalasa bile, zaman damgası farklı olacağı için yeniden kullanamaz.
Doğrulama Örnekleri
Node.js
const crypto = require('crypto');
function verifyWebhook(secret, signature, timestamp, body) {
const signablePayload = `${timestamp}.${body}`;
const hmac = crypto.createHmac('sha256', secret);
hmac.update(signablePayload, 'utf8');
const expected = `sha256=${hmac.digest('hex')}`;
// Zamanlama saldırılarını önlemek için sabit zamanlı karşılaştırma kullanın
if (signature.length !== expected.length) return false;
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// Uç nokta işleyicinizde:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-yapl-signature-256'];
const timestamp = req.headers['x-yapl-timestamp'];
const body = req.rawBody; // Ham istek gövdesi (string olarak)
if (!verifyWebhook(SIZIN_SIRRINIZ, signature, timestamp, body)) {
return res.status(401).send('Geçersiz imza');
}
// Webhook'u işleyin
const event = JSON.parse(body);
console.log(`${event.type} alındı:`, event.data);
res.status(200).send('OK');
});Python
import hmac
import hashlib
def verify_webhook(secret, signature, timestamp, body):
signable_payload = f"{timestamp}.{body}"
expected = "sha256=" + hmac.new(
secret.encode('utf-8'),
signable_payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# Uç nokta işleyicinizde (Flask örneği):
@app.route('/webhook', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-YAPL-Signature-256')
timestamp = request.headers.get('X-YAPL-Timestamp')
body = request.get_data(as_text=True)
if not verify_webhook(SIZIN_SIRRINIZ, signature, timestamp, body):
return 'Geçersiz imza', 401
event = request.get_json()
print(f"{event['type']} alındı: {event['data']}")
return 'OK', 200Go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
)
func verifyWebhook(secret, signature, timestamp, body string) bool {
signablePayload := fmt.Sprintf("%s.%s", timestamp, body)
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(signablePayload))
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(signature), []byte(expected))
}
func webhookHandler(w http.ResponseWriter, r *http.Request) {
signature := r.Header.Get("X-YAPL-Signature-256")
timestamp := r.Header.Get("X-YAPL-Timestamp")
body, _ := io.ReadAll(r.Body)
if !verifyWebhook(sizinSirriniz, signature, timestamp, string(body)) {
http.Error(w, "Geçersiz imza", http.StatusUnauthorized)
return
}
// Webhook'u işleyin
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}Güvenlik Önerileri
Her zaman imzaları doğrulayın
Test için bile imza doğrulamasını atlamayın. Doğrulanmamış uç noktalar sahte isteklere karşı savunmasızdır.
Sabit zamanlı karşılaştırma kullanın
Zamanlama saldırılarını önlemek için her zaman sabit zamanlı karşılaştırma fonksiyonları kullanın (Node.js'de crypto.timingSafeEqual veya Python'da hmac.compare_digest gibi).
Zaman damgasını kontrol edin
Tekrar saldırılarını önlemek için X-YAPL-Timestamp başlığının güncel olduğunu doğrulayın (örn. son 5 dakika içinde):
const deliveryTime = new Date(timestamp).getTime();
const now = Date.now();
const fiveMinutes = 5 * 60 * 1000;
if (Math.abs(now - deliveryTime) > fiveMinutes) {
return res.status(401).send('Teslimat çok eski');
}Sırları güvenli şekilde saklayın
- Sırları asla kaynak koduna yazmayın
- Ortam değişkenleri veya sır yöneticisi kullanın
- İhlal şüpheniz varsa yeni bir webhook oluşturarak sırrı yenileyin
HTTPS kullanın
Alıcı uç noktanız, webhook yükünü aktarım sırasında korumak için her zaman HTTPS kullanmalıdır. YAPL, üretim webhook URL'leri için HTTPS gerektirir.
İlgili Konular
- Webhook Oluşturma — Uç noktaları oluşturun ve imzalama sırrınızı alın
- Olay Türleri — Teslimatları tetikleyen olaylar
- Teslimat Kayıtları — Teslimat durumunu izleyin
Bu sayfa yardımcı oldu mu?