Skip to content

Keep platform cookies away from external upstreams - #52

Merged
thorwhalen merged 2 commits into
mainfrom
harden-external-proxy-cookies
Sep 22, 2026
Merged

thorwhalen merged 2 commits into
mainfrom
harden-external-proxy-cookies

Conversation

@thorwhalen

@thorwhalen thorwhalen commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

mode="external" apps proxy to a server outside the platform. The proxy forwarded every request header, including the visitor's Cookie, and passed every upstream response header back on the platform origin.

This change:

  • adds optional cookie_filter (name -> bool), drop_request_headers and drop_response_headers to make_proxy_app; rejected cookies are removed from the forwarded Cookie header, and upstream Set-Cookie headers naming them — or naming no cookie at all — are dropped;
  • adds platform_cookie_filter() (drops enlace_session, enlace_csrf, shared_auth_*);
  • makes ExternalStrategy use it (honouring a custom [auth] session_cookie_name), withhold X-CSRF-Token upstream, and drop Clear-Site-Data / Service-Worker-Allowed from upstream responses.

Process-mode (local, part of the platform) and asgi-mode apps are unchanged. Upstream-owned cookies and other headers still pass both ways (including Authorization, which an external API may use for its own tokens).

Limit (by design, not fixed here): an external app is still served on the platform origin, so HTML/JS it returns runs same-origin with the platform (it can issue credentialed same-origin requests, and read the non-HttpOnly CSRF cookie). This PR stops the platform credential from being handed to the upstream and stops response headers from overwriting/wiping it; it does not isolate a hostile upstream. Only a separate origin (own subdomain, or linking to the upstream directly) does that.

Tests: enlace/tests/test_proxy_cookies.py (fails on main). Independent refute-review done; its findings (nameless Set-Cookie, Clear-Site-Data, Service-Worker-Allowed, CSRF header) are fixed in the second commit. Dependents checked locally against this branch: enlace_auth (377 passed), enlace_docker (53 passed, 2 skipped).

🤖 Generated with Claude Code

thorwhalen and others added 2 commits September 22, 2026 14:54
mode="external" proxies now drop the platform's own cookies (session,
CSRF, shared-password) from forwarded requests and drop upstream Set-Cookie
headers that would set them on the platform origin. A custom
[auth] session_cookie_name is honoured. make_proxy_app gains an optional
cookie_filter; process-mode proxies are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Drop nameless Set-Cookie values (=enlace_session=x is sent by browsers as
  enlace_session=x and would shadow the real cookie).
- External apps: withhold X-CSRF-Token upstream; drop Clear-Site-Data and
  Service-Worker-Allowed from upstream responses.
- make_proxy_app gains drop_request_headers / drop_response_headers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thorwhalen
thorwhalen merged commit a164acd into main Sep 22, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the harden-external-proxy-cookies branch September 22, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant