GuardAPI Logo
GuardAPI

Fix Insecure Webhooks in Ktor

Webhooks are essentially unauthenticated POST endpoints unless you implement cryptographic verification. In Ktor, failing to validate the source of a webhook allows attackers to spoof events—like marking an unpaid order as 'paid' or triggering administrative actions. To secure them, you must verify the payload signature (HMAC) using a shared secret and a constant-time comparison.

The Vulnerable Pattern

post("/webhooks/stripe") {
    // VULNERABILITY: No signature verification
    // An attacker can POST any JSON to this endpoint
    val event = call.receive()
if (event.type == "payment_intent.succeeded") {
    orderService.fulfillOrder(event.data.orderId)
}
call.respond(HttpStatusCode.OK)

}

The Secure Implementation

The secure implementation enforces three critical layers: 1. It retrieves the raw request body as text to ensure the hash matches exactly what the provider sent. 2. It calculates a SHA256 HMAC using a shared secret stored in environment variables. 3. It utilizes MessageDigest.isEqual() for the signature comparison; this is a 'constant-time' operation that prevents attackers from using timing side-channels to brute-force the valid signature byte-by-byte.

post("/webhooks/stripe") {
    val payload = call.receiveText()
    val signature = call.request.header("X-Hub-Signature-256") 
        ?: return@post call.respond(HttpStatusCode.Unauthorized)
val secret = System.getenv("WEBHOOK_SECRET")
val hmac = Mac.getInstance("HmacSHA256")
val secretKey = MessageFormatSpec(secret.toByteArray(), "HmacSHA256")
hmac.init(secretKey)
val expectedSignature = hmac.doFinal(payload.toByteArray()).toHexString()

// Use MessageDigest.isEqual for constant-time comparison to prevent timing attacks
if (!MessageDigest.isEqual(signature.toByteArray(), expectedSignature.toByteArray())) {
    return@post call.respond(HttpStatusCode.Forbidden)
}

val event = Json.decodeFromString<WebhookEvent>(payload)
orderService.fulfillOrder(event.data.orderId)
call.respond(HttpStatusCode.OK)

}

System Alert • ID: 7341
Target: Ktor API
Potential Vulnerability

Your Ktor API might be exposed to Insecure Webhooks

74% of Ktor 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.