PST-069: A client-supplied X-Request-ID is accepted verbatim and echoed, so a stranger can borrow another request's id in the logs #798

Closed
opened 2026-10-10 10:56:40 +00:00 by tiagoagueda · 1 comment
Owner

Found in the security audit of 2026-10-10 (SECURITY-AUDIT-2026-10-10.md), run against main at c30851b from 8 to 10 October 2026, as PST-069. Severity: Informational.

The text below is the audit's entry, unchanged apart from links to the other issues it names. The finding was produced by automated review and checked by a second automated pass; re-check it before acting on it.


  • Severity: Informational
  • Category: log-correlation-spoofing
  • Location: src/postulo/core/middleware.py (216-225)
  • Found by: CSRF, methods and redirects

Who can do it, and what they need. Any client; no precondition. A reverse proxy that generates its own id but does not overwrite an incoming one passes the client's value through.

How it works.

  1. Attacker sends X-Request-ID: <id of a request they want to muddy or claim>.
  2. RequestIDMiddleware accepts anything matching [A-Za-z0-9._:-]{1,200} and binds it to every log line of the request, then echoes it.
  3. An operator correlating logs by id sees the attacker's lines interleaved under another request's id. Scratch test: GET /healthz with X-Request-ID: spoofed-id-of-another-request was answered with that same id.

Impact. Confuses incident forensics; no injection (newlines and other characters are refused) and no data exposure.

Verification (verdict: confirmed; severity after verification: Informational). No correction to file or line. Precondition clarified: to muddy a specific other request's log lines the attacker must know that request's id, which is a random 32-hex uuid4 or the proxy's own; without that, the only effect is that a client's own lines carry an id it chose, which is the feature. Remediation: document that a reverse proxy in front should overwrite X-Request-ID (or make honouring an inbound id conditional on the request arriving from a trusted proxy address, which TrustedProxyMiddleware already identifies).

Suggested remediation. Accept an incoming id only from a trusted proxy peer (reuse proxy.is_trusted / POSTULO_PROXY_ADDR) and mint a fresh one otherwise, or append a server-side suffix so the two are distinguishable.

Found in the security audit of 2026-10-10 (`SECURITY-AUDIT-2026-10-10.md`), run against `main` at `c30851b` from 8 to 10 October 2026, as **PST-069**. Severity: **Informational**. The text below is the audit's entry, unchanged apart from links to the other issues it names. The finding was produced by automated review and checked by a second automated pass; re-check it before acting on it. --- - **Severity:** Informational - **Category:** log-correlation-spoofing - **Location:** `src/postulo/core/middleware.py` (216-225) - **Found by:** CSRF, methods and redirects **Who can do it, and what they need.** Any client; no precondition. A reverse proxy that generates its own id but does not overwrite an incoming one passes the client's value through. **How it works.** 1. Attacker sends `X-Request-ID: <id of a request they want to muddy or claim>`. 2. RequestIDMiddleware accepts anything matching `[A-Za-z0-9._:-]{1,200}` and binds it to every log line of the request, then echoes it. 3. An operator correlating logs by id sees the attacker's lines interleaved under another request's id. Scratch test: `GET /healthz` with `X-Request-ID: spoofed-id-of-another-request` was answered with that same id. **Impact.** Confuses incident forensics; no injection (newlines and other characters are refused) and no data exposure. **Verification** (verdict: confirmed; severity after verification: Informational). No correction to file or line. Precondition clarified: to muddy a specific other request's log lines the attacker must know that request's id, which is a random 32-hex uuid4 or the proxy's own; without that, the only effect is that a client's own lines carry an id it chose, which is the feature. Remediation: document that a reverse proxy in front should overwrite X-Request-ID (or make honouring an inbound id conditional on the request arriving from a trusted proxy address, which TrustedProxyMiddleware already identifies). **Suggested remediation.** Accept an incoming id only from a trusted proxy peer (reuse `proxy.is_trusted` / `POSTULO_PROXY_ADDR`) and mint a fresh one otherwise, or append a server-side suffix so the two are distinguishable.
tiagoagueda added this to the 1.0.0 milestone 2026-10-10 10:58:05 +00:00
Author
Owner

Fixed in 0ca79b4a8 on main.

Fixed in 0ca79b4a8 on main.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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
Postulo/postulo#798
No description provided.