/proxy is an open, unauthenticated SSRF-capable server-side fetcher #2

Closed
opened 2026-07-28 21:00:47 +00:00 by paulloth1 · 1 comment
paulloth1 commented 2026-07-28 21:00:47 +00:00 (Migrated from github.com)

Problem

GET /proxy?url=<any-url>&cookies=<any-cookie-header> (backend/app.py) fetches an arbitrary caller-supplied URL server-side with httpx, no allowlist/scheme restriction, and echoes the (lightly rewritten) response back to the caller — with whatever cookies string the caller supplies forwarded as a raw Cookie: header.

There is currently no authentication anywhere on the admin UI or API (see separate issue), and the backend listens on 0.0.0.0:80/443/8080 — reachable by anyone on the hackerspace LAN/WiFi.

Impact

Combined, this means any device on the LAN can use the Pi as an open server-side HTTP proxy:

  • Probe/fetch internal-only or otherwise-firewalled hosts reachable from the Pi (e.g. the 3D printer's own network segment) and read the response.
  • Send arbitrary attacker-chosen cookies to arbitrary destination hosts via the cookies param (e.g. exfiltrate a cookie value to a third party by pointing url at an attacker-controlled endpoint).
  • Use the Pi's IP as an anonymizing relay for outbound requests.

Suggested fix

  • Restrict /proxy to an allowlist of hostnames actually configured in existing slides (or require it to be invoked only with a slide_id, looking up the URL/cookies server-side from stored config rather than accepting them as free-form request params).
  • At minimum, add authentication in front of all of /admin, /proxy, and the mutating /admin/* POST routes (see separate issue).
## Problem `GET /proxy?url=<any-url>&cookies=<any-cookie-header>` (`backend/app.py`) fetches an arbitrary caller-supplied URL server-side with `httpx`, no allowlist/scheme restriction, and echoes the (lightly rewritten) response back to the caller — with whatever `cookies` string the caller supplies forwarded as a raw `Cookie:` header. There is currently **no authentication anywhere** on the admin UI or API (see separate issue), and the backend listens on `0.0.0.0:80`/`443`/`8080` — reachable by anyone on the hackerspace LAN/WiFi. ## Impact Combined, this means any device on the LAN can use the Pi as an open server-side HTTP proxy: - Probe/fetch internal-only or otherwise-firewalled hosts reachable from the Pi (e.g. the 3D printer's own network segment) and read the response. - Send arbitrary attacker-chosen cookies to arbitrary destination hosts via the `cookies` param (e.g. exfiltrate a cookie value to a third party by pointing `url` at an attacker-controlled endpoint). - Use the Pi's IP as an anonymizing relay for outbound requests. ## Suggested fix - Restrict `/proxy` to an allowlist of hostnames actually configured in existing slides (or require it to be invoked only with a `slide_id`, looking up the URL/cookies server-side from stored config rather than accepting them as free-form request params). - At minimum, add authentication in front of all of `/admin`, `/proxy`, and the mutating `/admin/*` POST routes (see separate issue).
paulloth1 commented 2026-07-28 21:12:25 +00:00 (Migrated from github.com)

By design: /proxy fetching arbitrary public URLs is the intended behavior (embedding whatever content people want). Leaving it fully open per explicit decision — no IP-range restrictions added.

By design: /proxy fetching arbitrary public URLs is the intended behavior (embedding whatever content people want). Leaving it fully open per explicit decision — no IP-range restrictions added.
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
paul_loth/krautspaceTV#2
No description provided.