GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix Insecure Webhooks
in .NET 8 Web API

Executive Summary

Webhooks are essentially reverse APIs. If you are blindly accepting POST requests without verifying the source, you are inviting attackers to perform unauthorized actions or inject malicious data. In .NET 8, a common mistake is trusting the payload based solely on the endpoint's existence. A secure implementation requires HMAC-SHA256 signature verification to ensure the request originated from a trusted provider and wasn't tampered with in transit.

The Vulnerable Pattern

VULNERABLE CODE
[HttpPost("api/webhooks/receive")]
public IActionResult ReceiveWebhook([FromBody] dynamic payload)
{
    // VULNERABILITY: No signature verification. 
    // Anyone can POST any JSON to this endpoint.
    _logger.LogInformation("Processing payload: {Payload}", payload);
    return Ok();
}

The Secure Implementation

The secure implementation enforces three critical layers: 1. Shared Secret: Only the sender and receiver know the key used to sign the payload. 2. HMAC Verification: We re-calculate the HMAC-SHA256 hash of the raw request body and compare it to the provider's header. 3. Constant-Time Comparison: Using CryptographicOperations.FixedTimeEquals prevents side-channel timing attacks that could allow an attacker to brute-force the signature byte-by-byte. Always read the raw body for hash calculation before deserialization to ensure data integrity.

SECURE CODE
[HttpPost("api/webhooks/receive")]
public async Task ReceiveWebhook()
{
    var secret = _configuration["WebhookSettings:Secret"];
    if (!Request.Headers.TryGetValue("X-Hub-Signature-256", out var signature))
        return Unauthorized("Missing signature.");
using var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var keyBytes = Encoding.UTF8.GetBytes(secret);
var bodyBytes = Encoding.UTF8.GetBytes(body);

using var hmac = new HMACSHA256(keyBytes);
var hashBytes = hmac.ComputeHash(bodyBytes);
var expectedSignature = "sha256=" + Convert.ToHexString(hashBytes).ToLower();

// Use FixedTimeEquals to prevent timing attacks
if (!CryptographicOperations.FixedTimeEquals(
    Encoding.UTF8.GetBytes(expectedSignature), 
    Encoding.UTF8.GetBytes(signature)))
{
    return Unauthorized("Invalid signature.");
}

var payload = JsonSerializer.Deserialize<WebhookDto>(body);
return Ok();

}

System Alert • ID: 3729
Target: .NET 8 Web API API
Potential Vulnerability

Your .NET 8 Web API API might be exposed to Insecure Webhooks

74% of .NET 8 Web API apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.