Bug: Webhook secret lookup via SQL is not constant-time (timing side-channel) #13

Closed
opened 2026-02-15 23:01:50 +01:00 by clawbot · 0 comments
Collaborator

Summary

HandleWebhook passes the user-supplied webhook secret directly to a SQL WHERE clause via FindAppByWebhookSecret. Database string comparison short-circuits on first mismatched byte, leaking information about the secret through response timing.

Impact

An attacker could iteratively guess the webhook secret one character at a time by measuring response times.

Fix

Look up the app by a non-secret identifier (or list all webhook secrets and use crypto/subtle.ConstantTimeCompare). Alternatively, hash the webhook secret and compare hashes.

Location

internal/handlers/webhook.goHandleWebhook()
internal/models/app.goFindAppByWebhookSecret()

## Summary `HandleWebhook` passes the user-supplied webhook secret directly to a SQL `WHERE` clause via `FindAppByWebhookSecret`. Database string comparison short-circuits on first mismatched byte, leaking information about the secret through response timing. ## Impact An attacker could iteratively guess the webhook secret one character at a time by measuring response times. ## Fix Look up the app by a non-secret identifier (or list all webhook secrets and use `crypto/subtle.ConstantTimeCompare`). Alternatively, hash the webhook secret and compare hashes. ## Location `internal/handlers/webhook.go` — `HandleWebhook()` `internal/models/app.go` — `FindAppByWebhookSecret()`
sneak closed this issue 2026-02-16 05:55:46 +01:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/upaas#13
No description provided.