Request log: an ampersand in query or referer is written as \u0026 #327

Closed
opened 2026-11-11 04:09:01 +01:00 by clawbot · 2 comments
Collaborator

Not blocking: need not be fixed before real traffic. Found by the end-to-end check of sww rproxy (#321) on next at f7e3190.

Where

internal/requestlog/requestlog.go, writeJSONLine (json.Marshal, line 257). Every request line of rproxy and of waf is written through it.

What is wrong

An ampersand, a less-than sign or a greater-than sign in a field of a request line is written as \u0026, \u003c or \u003e.

A request for /search?a=1&b=2 is logged with "query":"a=1\u0026b=2". The same holds for referer.

A JSON parser reads the value back correctly. The line as written does not hold the query string the visitor sent. Process lines write the same characters as they are, so the two kinds of line in one log differ.

Why it matters

  • AGENTS.md says the request log records query strings exactly as received.
  • An operator who searches the log for a query string with grep finds nothing: nearly every query string with two parameters holds an ampersand.

Acceptable

A request line holds those three characters as they were sent, and is still valid JSON. Go's json.Encoder does this with SetEscapeHTML(false). A test logs a query string with an ampersand and reads the line as text.

docs/request-log.md needs no change: it does not mention the escaping.

Disclosures

  • Confidence: high that it happens. That it is a defect is a judgement call, since the decoded value is right.

Definition of done

  • One PR to next.
  • make check passes.

Model: fable-5-2

Not blocking: need not be fixed before real traffic. Found by the end-to-end check of `sww rproxy` (https://git.eeqj.de/sneak/smallwebwaf/issues/321) on `next` at `f7e3190`. ## Where `internal/requestlog/requestlog.go`, `writeJSONLine` (`json.Marshal`, line 257). Every request line of `rproxy` and of `waf` is written through it. ## What is wrong An ampersand, a less-than sign or a greater-than sign in a field of a request line is written as `\u0026`, `\u003c` or `\u003e`. A request for `/search?a=1&b=2` is logged with `"query":"a=1\u0026b=2"`. The same holds for `referer`. A JSON parser reads the value back correctly. The line as written does not hold the query string the visitor sent. Process lines write the same characters as they are, so the two kinds of line in one log differ. ## Why it matters - `AGENTS.md` says the request log records query strings exactly as received. - An operator who searches the log for a query string with `grep` finds nothing: nearly every query string with two parameters holds an ampersand. ## Acceptable A request line holds those three characters as they were sent, and is still valid JSON. Go's `json.Encoder` does this with `SetEscapeHTML(false)`. A test logs a query string with an ampersand and reads the line as text. `docs/request-log.md` needs no change: it does not mention the escaping. ## Disclosures - Confidence: high that it happens. That it is a defect is a judgement call, since the decoded value is right. ## Definition of done - One PR to `next`. - `make check` passes. Model: fable-5-2
Author
Collaborator

Plan. Build the "Acceptable" section above: request lines are written with HTML escaping off, so &, < and > appear as sent, and each line is still one valid JSON object on one line. This follows the iron rule in AGENTS.md that the request log records query strings exactly as received.

Package: internal/requestlog (writeJSONLine), whose doc says it writes the logs. If the remote log or alerts send the same lines through another path, that path gets the same change; name it in the PR body. The test logs a query string and a referer holding &, < and >, reads the line as text, and finds them unchanged.

Follow AGENTS.md: checks only through make targets. make fmt, then flock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check; a flock timeout also exits 1, so read the output. Edit by hand. Title ending (closes #327). Label the PR needs-review.

Model: opus-5-5

**Plan.** Build the "Acceptable" section above: request lines are written with HTML escaping off, so `&`, `<` and `>` appear as sent, and each line is still one valid JSON object on one line. This follows the iron rule in `AGENTS.md` that the request log records query strings exactly as received. Package: `internal/requestlog` (`writeJSONLine`), whose doc says it writes the logs. If the remote log or alerts send the same lines through another path, that path gets the same change; name it in the PR body. The test logs a query string and a referer holding `&`, `<` and `>`, reads the line as text, and finds them unchanged. Follow `AGENTS.md`: checks only through `make` targets. `make fmt`, then `flock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check`; a `flock` timeout also exits 1, so read the output. Edit by hand. Title ending ` (closes #327)`. Label the PR `needs-review`. Model: opus-5-5
clawbot self-assigned this 2026-11-11 04:11:38 +01:00
Author
Collaborator

Built in #329: request lines now hold ampersands, less-than signs and greater-than signs as sent. Alert webhooks and the report rproxy posts to waf are unchanged, since neither is a request line.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/smallwebwaf/pulls/329: request lines now hold ampersands, less-than signs and greater-than signs as sent. Alert webhooks and the report `rproxy` posts to `waf` are unchanged, since neither is a request line. 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/smallwebwaf#327