webhooker logs the entrypoint UUID at INFO although the README says to keep it out of logs #531

Closed
opened 2026-10-13 11:35:27 +02:00 by clawbot · 2 comments
Collaborator

Severity: medium

Found by the v1.0.0-rc1 audit. The README contradicts itself and the code about whether an entrypoint URL belongs in logs. Under "The entrypoint URL is the authentication secret", the README says "Keep it out of logs". But:

  • webhooker's own http request access log line and the webhook request received line (internal/handlers/webhook.go) write the entrypoint UUID at INFO on every accepted event;
  • the README's reverse-proxy section ("Keep the proxy's access log") recommends an nginx log that records the full request path, UUID included.

Sentry already withholds the UUID (#179), so the repo's own rule is that the UUID is not written where it can be read later.

Done when:

  • webhooker's own log lines identify a received request by its route pattern and the entrypoint's internal ID, never the UUID, with a test that an accepted event's log output carries no UUID;
  • the README's proxy advice says how to keep the UUID out of the proxy's access log, or says plainly that the proxy's log holds it and must be protected like the URL itself;
  • every README sentence about logging the receiver is true against the code.

Model: fable-5-1 (audit); opus-5-5 (issue)

Severity: medium Found by the `v1.0.0-rc1` audit. The README contradicts itself and the code about whether an entrypoint URL belongs in logs. Under "The entrypoint URL is the authentication secret", the README says "Keep it out of logs". But: - webhooker's own `http request` access log line and the `webhook request received` line (`internal/handlers/webhook.go`) write the entrypoint UUID at INFO on every accepted event; - the README's reverse-proxy section ("Keep the proxy's access log") recommends an nginx log that records the full request path, UUID included. Sentry already withholds the UUID (https://git.eeqj.de/sneak/webhooker/issues/179), so the repo's own rule is that the UUID is not written where it can be read later. Done when: - webhooker's own log lines identify a received request by its route pattern and the entrypoint's internal ID, never the UUID, with a test that an accepted event's log output carries no UUID; - the README's proxy advice says how to keep the UUID out of the proxy's access log, or says plainly that the proxy's log holds it and must be protected like the URL itself; - every README sentence about logging the receiver is true against the code. Model: fable-5-1 (audit); opus-5-5 (issue)
clawbot self-assigned this 2026-10-13 11:35:27 +02:00
Author
Collaborator

Plan: no log line webhooker writes carries an entrypoint UUID.

  • Access log (accessLogURL in internal/middleware/middleware.go): for the receiver route, log the chi route pattern whatever the status, never the concrete path; other routes keep today's rule.
  • webhook request received in internal/handlers/webhook.go: log the entrypoint's internal ID (and webhook ID if at hand) instead of entrypoint_uuid. A request for an unknown UUID logs no UUID either.
  • Audit every other line that can log a receiver path (the rate limiter, CSRF, login guard and anything else that logs r.URL.Path) and apply the same rule.
  • README: under "The URL is a capability", and in the proxy section's "Keep the proxy's access log" step, say plainly that the proxy's access log holds the UUID and must be protected like the URL itself; every README sentence about what webhooker logs for the receiver matches the code.
  • Test: an accepted event, an unknown UUID and a rate-limited receiver request each produce log output with no UUID in it.

Model: opus-5-5

Plan: no log line webhooker writes carries an entrypoint UUID. - Access log (`accessLogURL` in `internal/middleware/middleware.go`): for the receiver route, log the chi route pattern whatever the status, never the concrete path; other routes keep today's rule. - `webhook request received` in `internal/handlers/webhook.go`: log the entrypoint's internal ID (and webhook ID if at hand) instead of `entrypoint_uuid`. A request for an unknown UUID logs no UUID either. - Audit every other line that can log a receiver path (the rate limiter, CSRF, login guard and anything else that logs `r.URL.Path`) and apply the same rule. - README: under "The URL is a capability", and in the proxy section's "Keep the proxy's access log" step, say plainly that the proxy's access log holds the UUID and must be protected like the URL itself; every README sentence about what webhooker logs for the receiver matches the code. - Test: an accepted event, an unknown UUID and a rate-limited receiver request each produce log output with no UUID in it. Model: opus-5-5
Author
Collaborator

Built in #534, following the plan above: on the receiver route the access log and the 429 line name the route pattern, the received line names the entrypoint and webhook IDs, and the unknown-entrypoint line logs no path. The README now says the proxy access log holds the UUID and must be protected like the URL.

One addition to the plan: the route pattern is a new constant, middleware.ReceiverRoute, which routes.go registers the receiver with.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/webhooker/pulls/534, following the plan above: on the receiver route the access log and the 429 line name the route pattern, the received line names the entrypoint and webhook IDs, and the unknown-entrypoint line logs no path. The README now says the proxy access log holds the UUID and must be protected like the URL. One addition to the plan: the route pattern is a new constant, `middleware.ReceiverRoute`, which `routes.go` registers the receiver with. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#531