YAPL Dokümantasyon
Kullanım KılavuzlarıWebhook'lar

İ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

  1. Bir webhook oluşturduğunuzda YAPL benzersiz bir imzalama sırrı üretir
  2. Her teslimat için YAPL, sırrınızı ve yükü kullanarak bir HMAC-SHA256 imzası hesaplar
  3. İmza, X-YAPL-Signature-256 istek başlığına eklenir
  4. 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ıkAçıklamaÖrnek
X-YAPL-Signature-256HMAC-SHA256 imzasısha256=a1b2c3d4...
X-YAPL-EventOlay türüproject.created.v1
X-YAPL-Delivery-IDBenzersiz 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', 200

Go

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

Bu sayfa yardımcı oldu mu?

Bu Sayfada