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.
## 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()`
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
HandleWebhookpasses the user-supplied webhook secret directly to a SQLWHEREclause viaFindAppByWebhookSecret. 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()