Webhook Sahteciliği Açığı
<p>Smart Tech Devs'te bir B2B SaaS platformu geliştirirken, Stripe, Shopify veya GitHub gibi dış hizmetlere bağımlı olmak kaçınılmazdır. Bu hizmetler, bir olay gerçekleştiğinde (örneğin, <code>invoice.paid</code>) sunucunuza otomatik HTTP POST istekleri gönderen Webhooks aracılığıyla uygulamanızla iletişim kurarlar.</p>
<p>Geliştiricilerin, <code>/api/webhooks/billing</code> uç noktasına ulaşan verilere körü körüne güvenmesi, felaket bir güvenlik açığına yol açar. Çünkü webhooks, kamuya açık URL'lerdir ve kötü niyetli bir kişi, Postman kullanarak sunucunuza sahte bir JSON yükü gönderebilir ve 10,000 dolarlık bir işletme faturası başarıyla ödendi iddiasında bulunabilir. Eğer kontrolcünüz bu yükü doğrulama yapmadan işlerse, bir saldırgana platformunuza ücretsiz ömür boyu erişim sağladınız demektir. Zero-trust API'ler oluşturmak için, HMAC İmza Doğrulama uygulamanız gerekir.</p>
<h2>Kritik Çözüm: HMAC-SHA256</h2>
<p>Kurumsal webhook sağlayıcıları, yalnızca bir JSON gövdesi göndermekle kalmaz; ayrıca HTTP başlıklarında bir kriptografik imza da gönderirler (örneğin, <code>Stripe-Signature</code>). Bu imza, yük gövdesi ve yalnızca sizin ve sağlayıcının bildiği bir gizli anahtar kullanılarak oluşturulmuş bir hash'tir.</p>
<p>Laravel uygulamanız isteği aldığında, gelen gövdeyi kendi gizli anahtarınızla bağımsız olarak hash'lemelidir. Eğer hesapladığınız hash, başlık imzasıyla tam olarak eşleşiyorsa, yük matematiksel olarak gerçek ve bozulmamış olarak kanıtlanmış olur.</p>
<h3>Evrensel Webhook Koruma Middleware'ini Tasarlamak</h3>
<p>Bu doğrulamayı Middleware katmanında zorunlu kılarak kötü niyetli isteklerin iş mantığı kontrolcülerimize ulaşmasını engelleyebiliriz.</p>
<pre><code>namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class VerifyWebhookSignature
{
public function handle(Request $request, Closure $next): Response
{
// 1. Dış tedarikçiden sağlanan imzayı çıkar
$signatureHeader = $request->header(‘X-Vendor-Signature’);
if (! $signatureHeader) {
\Log::warning('Webhook reddedildi: İmza başlığı eksik.', ['ip' => $request->ip()]);
return response()->json(['error' => 'Yetkisiz erişim'], 401);
}
// 2. Güvenli webhook imzalama sırrınızı .env dosyasından al
$secret = config('services.vendor.webhook_secret');
// 3. HMAC-SHA256 hash'ini ham ve ayrıştırılmamış istek gövdesi kullanarak hesapla
$computedSignature = hash_hmac('sha256', $request->getContent(), $secret);
// 4. KRİTİK: Timing Attacks'leri önlemek için hash_equals() kullanın!
// Normal string karşılaştırma (===) yanlış karakterlerde daha hızlı başarısız olur,
// bu da saldırganların hash karakterini karakter karakter tahmin etmesine neden olur.
if (! hash_equals($computedSignature, $signatureHeader)) {
\Log::alert('Webhook reddedildi: Geçersiz imza tespit edildi.', ['ip' => $request->ip()]);
return response()->json(['error' => 'Geçersiz imza'], 403);
}
// Yük güvenilir. Kontrolcüye devam et.
return $next($request);
}}
<h2>Mühendislik ROI'si</h2>
<p>Webhook rotalarınızda HMAC imza doğrulamasını zorunlu kılarak, gelen veri akışlarınız üzerinde mutlak kriptografik kesinlik sağlarsınız. Yük sahtekarlığı, tekrar saldırıları ve yetkisiz sistem değişiklikleri riskini tamamen ortadan kaldırarak, finansal ve operasyonel hatlarınızı dış manipülasyona karşı güvence altına alırsınız.</p>Kaynak: Orijinal Makale


