requestEventSource (internal/handlers/webhook.go) stores the method, headers, content type and body of a received request. It does not store the query string. A sender that carries information in URL parameters (a token, an event name, a signature) loses it on receipt: it is not in the event log, it is not archived, and an HTTP target never sees it. Nothing in the README says so.
Found by the 1.0 readiness review (#311); the audit at #303 noted it as a minor finding.
Definition of done
The raw query string of the receiving request is stored on the event (a new column on the per-webhook events table; pre-1.0, so no migration file), including for resubmitted copies.
The event log renders it with the request line, and the archive and log targets carry it, using the same masking the access log applies if any part of it is treated as sensitive there.
The README's Event data model section documents the field.
Whether an HTTP target receives it (appended to the target URL, or as a header) is an owner decision asked on this issue; until answered, storing and showing it is the whole unit and delivery is unchanged.
A test posts to /webhook/{uuid}?a=1&b=2 and asserts the stored and rendered value.
Model: fable-5-1
`requestEventSource` (`internal/handlers/webhook.go`) stores the method, headers, content type and body of a received request. It does not store the query string. A sender that carries information in URL parameters (a token, an event name, a signature) loses it on receipt: it is not in the event log, it is not archived, and an HTTP target never sees it. Nothing in the README says so.
Found by the 1.0 readiness review (https://git.eeqj.de/sneak/webhooker/issues/311); the audit at https://git.eeqj.de/sneak/webhooker/issues/303 noted it as a minor finding.
## Definition of done
- The raw query string of the receiving request is stored on the event (a new column on the per-webhook `events` table; pre-1.0, so no migration file), including for resubmitted copies.
- The event log renders it with the request line, and the archive and log targets carry it, using the same masking the access log applies if any part of it is treated as sensitive there.
- The README's Event data model section documents the field.
- Whether an HTTP target receives it (appended to the target URL, or as a header) is an owner decision asked on this issue; until answered, storing and showing it is the whole unit and delivery is unchanged.
- A test posts to `/webhook/{uuid}?a=1&b=2` and asserts the stored and rendered value.
Model: fable-5-1
clawbot
added this to the 1.0.0 milestone 2026-09-21 09:20:19 +02:00
Question for the owner: once the query string is stored, should an HTTP target receive it?
Append it to the target URL on delivery (recommended): the target gets the request the sender meant to make, which is what a proxy is for, and a target URL that already has a query string gets the two joined with &. Replay and resubmit carry it the same way.
Send it as a header only (for example X-Webhooker-Query): the target URL stays exactly what the operator configured, and a target that wants the parameters reads the header.
Store and show only: never forwarded.
The unit as filed stops at storing and rendering; delivery changes only on your answer here.
Model: fable-5-1
Question for the owner: once the query string is stored, should an HTTP target receive it?
- Append it to the target URL on delivery (recommended): the target gets the request the sender meant to make, which is what a proxy is for, and a target URL that already has a query string gets the two joined with `&`. Replay and resubmit carry it the same way.
- Send it as a header only (for example `X-Webhooker-Query`): the target URL stays exactly what the operator configured, and a target that wants the parameters reads the header.
- Store and show only: never forwarded.
The unit as filed stops at storing and rendering; delivery changes only on your answer here.
Model: fable-5-1
sneak
was assigned by clawbot2026-09-21 09:20:58 +02:00
Found again by the audit for #377, on current next: an event posted to an entrypoint URL with ?source=storefront&attempt=1 shows no trace of the query string on any page.
Model: opus-5-5
Found again by the audit for https://git.eeqj.de/sneak/webhooker/issues/377, on current `next`: an event posted to an entrypoint URL with `?source=storefront&attempt=1` shows no trace of the query string on any page.
Model: opus-5-5
Labelled critical: a sender that carries information in the webhook URL's query string, such as a token or an event name, loses it on receipt, because webhooker never stores, shows or delivers the query string, so the operator gets events with part of their content silently missing.
Model: opus-5-5
Labelled critical: a sender that carries information in the webhook URL's query string, such as a token or an event name, loses it on receipt, because webhooker never stores, shows or delivers the query string, so the operator gets events with part of their content silently missing.
Model: opus-5-5
Ruling from sneak (chat, 2026-10-03 ~23:35 UTC): yes, an HTTP target may receive the query string, as a per-target setting that is off by default.
Definition of done (store and show, as filed, plus this):
Every received event stores the raw query string of the receiving request (including resubmitted copies), and the event log and per-event page show it with the request line, masked the same way the access log masks.
Each HTTP target gets a setting "pass the query string on to this target", off by default, on the HTTP target's form and its stored settings.
With the setting on, delivery appends the event's query string to the target URL; a target URL that already has a query string gets the two joined with &. Replay and resubmit behave the same.
With the setting off (the default), the target URL is exactly what the operator configured.
Tests cover storing and showing the query string, and delivery with the setting off, on, and on with a target URL that already has a query string.
The README describes the setting next to the HTTP target's other settings.
Lands on next after an independent review.
Model: opus-5-5
**Ruling from sneak** (chat, 2026-10-03 ~23:35 UTC): yes, an HTTP target may receive the query string, as a per-target setting that is **off by default**.
Definition of done (store and show, as filed, plus this):
- Every received event stores the raw query string of the receiving request (including resubmitted copies), and the event log and per-event page show it with the request line, masked the same way the access log masks.
- Each HTTP target gets a setting "pass the query string on to this target", off by default, on the HTTP target's form and its stored settings.
- With the setting on, delivery appends the event's query string to the target URL; a target URL that already has a query string gets the two joined with `&`. Replay and resubmit behave the same.
- With the setting off (the default), the target URL is exactly what the operator configured.
- Tests cover storing and showing the query string, and delivery with the setting off, on, and on with a target URL that already has a query string.
- The README describes the setting next to the HTTP target's other settings.
- Lands on `next` after an independent review.
Model: opus-5-5
sneak
was unassigned by clawbot2026-10-04 01:36:41 +02:00
clawbot
self-assigned this 2026-10-04 01:36:41 +02:00
Store: the receiver keeps the raw query string of the receiving request on the event, in a new column on the per-webhook events table added in place (pre-1.0, no migration). A resubmitted copy carries its original's query string, as it carries its headers.
Show: the expanded event in the event log and the event's own page show it with the request line, through the shared request template from #389. The event log cuts it at the same per-event size limit it applies to the request headers, with the same link to the event's page; the event's page shows it whole.
Archive and log targets carry it with the rest of the event; the log target writes it through the same per-field size budget as its other fields.
HTTP targets: a setting "pass the query string on to this target", off by default, on both target forms, in the stored settings and in the target list. On, delivery appends the event's query string to the target URL, joined with & when the URL already has one; replay and resubmit do the same. Off, the target URL is exactly what the operator configured. Delivery errors keep masking the target URL's secrets when a query string has been appended.
Tests for each of these; the README documents the stored field and the new setting.
Reading taken on "masked the same way the access log masks": the access log replaces the whole query with ?(redacted) because its size is unbounded, not because it is secret, so the access log is unchanged and the pages behind the sign-in bound the query string by size, as they already do for headers and the body, instead of hiding it.
Model: opus-5-5
Plan, following the ruling above:
- **Store:** the receiver keeps the raw query string of the receiving request on the event, in a new column on the per-webhook `events` table added in place (pre-1.0, no migration). A resubmitted copy carries its original's query string, as it carries its headers.
- **Show:** the expanded event in the event log and the event's own page show it with the request line, through the shared request template from https://git.eeqj.de/sneak/webhooker/issues/389. The event log cuts it at the same per-event size limit it applies to the request headers, with the same link to the event's page; the event's page shows it whole.
- **Archive and log targets** carry it with the rest of the event; the log target writes it through the same per-field size budget as its other fields.
- **HTTP targets:** a setting "pass the query string on to this target", off by default, on both target forms, in the stored settings and in the target list. On, delivery appends the event's query string to the target URL, joined with `&` when the URL already has one; replay and resubmit do the same. Off, the target URL is exactly what the operator configured. Delivery errors keep masking the target URL's secrets when a query string has been appended.
- **Tests** for each of these; the README documents the stored field and the new setting.
Reading taken on "masked the same way the access log masks": the access log replaces the whole query with `?(redacted)` because its size is unbounded, not because it is secret, so the access log is unchanged and the pages behind the sign-in bound the query string by size, as they already do for headers and the body, instead of hiding it.
Model: opus-5-5
clawbot
removed the critical label 2026-10-04 01:37:54 +02:00
sneak (chat, 2026-10-03 ~23:37 UTC): this is not a critical fix. The critical label is removed; the issue is normal priority in the queue, with the definition of done above unchanged.
Model: opus-5-5
sneak (chat, 2026-10-03 ~23:37 UTC): this is not a critical fix. The `critical` label is removed; the issue is normal priority in the queue, with the definition of done above unchanged.
Model: opus-5-5
#501 stores the query string of every received event (a resubmitted copy keeps its original's), shows it in the event log and on the event's page, and carries it in the archive and log targets. HTTP targets get a "Pass the query string on to this target" setting, off by default, that appends it to the target URL, joined with & to the URL's own; replays and resubmits do the same.
Judgement call: the access log is unchanged, per the reading in the plan above.
Not fixed here: a gap in masking an echoed request line for a target URL with a query string but no path, filed as #500.
Model: opus-5-5
https://git.eeqj.de/sneak/webhooker/pulls/501 stores the query string of every received event (a resubmitted copy keeps its original's), shows it in the event log and on the event's page, and carries it in the archive and log targets. HTTP targets get a "Pass the query string on to this target" setting, off by default, that appends it to the target URL, joined with `&` to the URL's own; replays and resubmits do the same.
- Judgement call: the access log is unchanged, per the reading in the plan above.
- Not fixed here: a gap in masking an echoed request line for a target URL with a query string but no path, filed as https://git.eeqj.de/sneak/webhooker/issues/500.
Model: opus-5-5
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.
requestEventSource(internal/handlers/webhook.go) stores the method, headers, content type and body of a received request. It does not store the query string. A sender that carries information in URL parameters (a token, an event name, a signature) loses it on receipt: it is not in the event log, it is not archived, and an HTTP target never sees it. Nothing in the README says so.Found by the 1.0 readiness review (#311); the audit at #303 noted it as a minor finding.
Definition of done
eventstable; pre-1.0, so no migration file), including for resubmitted copies./webhook/{uuid}?a=1&b=2and asserts the stored and rendered value.Model: fable-5-1
Question for the owner: once the query string is stored, should an HTTP target receive it?
&. Replay and resubmit carry it the same way.X-Webhooker-Query): the target URL stays exactly what the operator configured, and a target that wants the parameters reads the header.The unit as filed stops at storing and rendering; delivery changes only on your answer here.
Model: fable-5-1
Found again by the audit for #377, on current
next: an event posted to an entrypoint URL with?source=storefront&attempt=1shows no trace of the query string on any page.Model: opus-5-5
Labelled critical: a sender that carries information in the webhook URL's query string, such as a token or an event name, loses it on receipt, because webhooker never stores, shows or delivers the query string, so the operator gets events with part of their content silently missing.
Model: opus-5-5
Ruling from sneak (chat, 2026-10-03 ~23:35 UTC): yes, an HTTP target may receive the query string, as a per-target setting that is off by default.
Definition of done (store and show, as filed, plus this):
&. Replay and resubmit behave the same.nextafter an independent review.Model: opus-5-5
Plan, following the ruling above:
eventstable added in place (pre-1.0, no migration). A resubmitted copy carries its original's query string, as it carries its headers.&when the URL already has one; replay and resubmit do the same. Off, the target URL is exactly what the operator configured. Delivery errors keep masking the target URL's secrets when a query string has been appended.Reading taken on "masked the same way the access log masks": the access log replaces the whole query with
?(redacted)because its size is unbounded, not because it is secret, so the access log is unchanged and the pages behind the sign-in bound the query string by size, as they already do for headers and the body, instead of hiding it.Model: opus-5-5
sneak (chat, 2026-10-03 ~23:37 UTC): this is not a critical fix. The
criticallabel is removed; the issue is normal priority in the queue, with the definition of done above unchanged.Model: opus-5-5
#501 stores the query string of every received event (a resubmitted copy keeps its original's), shows it in the event log and on the event's page, and carries it in the archive and log targets. HTTP targets get a "Pass the query string on to this target" setting, off by default, that appends it to the target URL, joined with
&to the URL's own; replays and resubmits do the same.Model: opus-5-5