Repository navigation
serve: add CORS preflight (OPTIONS), reverse-proxy header support, and X-Accel-Buffering for SSE - #321
Closed
BlitzenCats wants to merge 1 commit into
Closed
serve: add CORS preflight (OPTIONS), reverse-proxy header support, and X-Accel-Buffering for SSE#321BlitzenCats wants to merge 1 commit into
BlitzenCats wants to merge 1 commit into
Conversation
…d X-Accel-Buffering for SSE - Implement do_OPTIONS (204 No Content) and add Access-Control-Allow-* headers to allow web-based clients (Open WebUI, LibreChat, browser extensions) to query endpoints. - Update _own_page to recognize reverse proxies and tunnels (Cloudflare Tunnel, Tailscale Funnel, Nginx) via X-Forwarded-Host, CF-Ray, and forwarded headers, preventing 403 CSRF false-positives when serving remotely. - Add X-Accel-Buffering: no to SSE streaming responses to prevent reverse proxies from buffering real-time token generation. - Add unit tests in serve/test_server.py covering CORS preflight, CORS headers, and reverse proxy origin checks. Co-authored-by: Gemini <gemini@google.com>
Owner
|
Thanks! This is in the 0.1.32 batch. We take it without the origin bypass on X-Forwarded-For / CF-* headers: with OPTIONS open to every origin, any web page could send such a header and then change settings or run MCP tools. CORS on /v1/* stays opt-in with a configured list of trusted origins; X-Accel-Buffering and the proxy headers stay; every change goes through our identity gate (byte-identical output on four models) and a speed A/B before it ships. |
Niko1221
added a commit
that referenced
this pull request
Oct 1, 2026
…e bypass for proxy headers
- The Origin check of /settings and the MCP tools let any page through when the request carried X-Forwarded-For,
CF-Ray or CF-Connecting-IP (headers every reverse proxy or tunnel adds), and compared hosts without their ports
(a page on another local port passed): any web page could then change the shared settings or run MCP tools with the
user's rights. Removed. The Origin must be this server's host:port, or an origin in the config's new
"trusted_origins" (the web app behind a proxy or tunnel); a proxy header alone opens nothing.
- CORS is opt-in: "cors_origins" in the config (an origin, a list, or "*"). Only /v1/* answers with
Access-Control-Allow-Origin (the origin itself, or "*"), never /settings, /unload or the app's files; the
preflight echoes the headers asked for ("*" does not cover Authorization). OPTIONS is answered 204 either way.
- X-Accel-Buffering: no on SSE stays. origins_of() checks both lists at start (scheme://host[:port], no paths;
"*" only for cors_origins). docs/DETAILS.md; tests for the bypasses, the trusted origin, CORS off/on, the header.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
Owner
|
Released in 0.1.32 without the X-Forwarded-For / CF-* origin bypass: CORS on /v1/* is opt-in with a trusted-origin list. Merged under your name (GitHub doesn't show it as merged because it went in by hand). Thank you! |
Niko1221
added a commit
that referenced
this pull request
Oct 6, 2026
…e bypass for proxy headers
- The Origin check of /settings and the MCP tools let any page through when the request carried X-Forwarded-For,
CF-Ray or CF-Connecting-IP (headers every reverse proxy or tunnel adds), and compared hosts without their ports
(a page on another local port passed): any web page could then change the shared settings or run MCP tools with the
user's rights. Removed. The Origin must be this server's host:port, or an origin in the config's new
"trusted_origins" (the web app behind a proxy or tunnel); a proxy header alone opens nothing.
- CORS is opt-in: "cors_origins" in the config (an origin, a list, or "*"). Only /v1/* answers with
Access-Control-Allow-Origin (the origin itself, or "*"), never /settings, /unload or the app's files; the
preflight echoes the headers asked for ("*" does not cover Authorization). OPTIONS is answered 204 either way.
- X-Accel-Buffering: no on SSE stays. origins_of() checks both lists at start (scheme://host[:port], no paths;
"*" only for cors_origins). docs/DETAILS.md; tests for the bypasses, the trusted origin, CORS off/on, the header.
anon761
pushed a commit
to anon761/Strata-upstream
that referenced
this pull request
Oct 6, 2026
… own-page bypass for proxy headers
- The Origin check of /settings and the MCP tools let any page through when the request carried X-Forwarded-For,
CF-Ray or CF-Connecting-IP (headers every reverse proxy or tunnel adds), and compared hosts without their ports
(a page on another local port passed): any web page could then change the shared settings or run MCP tools with the
user's rights. Removed. The Origin must be this server's host:port, or an origin in the config's new
"trusted_origins" (the web app behind a proxy or tunnel); a proxy header alone opens nothing.
- CORS is opt-in: "cors_origins" in the config (an origin, a list, or "*"). Only /v1/* answers with
Access-Control-Allow-Origin (the origin itself, or "*"), never /settings, /unload or the app's files; the
preflight echoes the headers asked for ("*" does not cover Authorization). OPTIONS is answered 204 either way.
- X-Accel-Buffering: no on SSE stays. origins_of() checks both lists at start (scheme://host[:port], no paths;
"*" only for cors_origins). docs/DETAILS.md; tests for the bypasses, the trusted origin, CORS off/on, the header.
anon761
pushed a commit
to anon761/Strata-upstream
that referenced
this pull request
Oct 6, 2026
… own-page bypass for proxy headers
- The Origin check of /settings and the MCP tools let any page through when the request carried X-Forwarded-For,
CF-Ray or CF-Connecting-IP (headers every reverse proxy or tunnel adds), and compared hosts without their ports
(a page on another local port passed): any web page could then change the shared settings or run MCP tools with the
user's rights. Removed. The Origin must be this server's host:port, or an origin in the config's new
"trusted_origins" (the web app behind a proxy or tunnel); a proxy header alone opens nothing.
- CORS is opt-in: "cors_origins" in the config (an origin, a list, or "*"). Only /v1/* answers with
Access-Control-Allow-Origin (the origin itself, or "*"), never /settings, /unload or the app's files; the
preflight echoes the headers asked for ("*" does not cover Authorization). OPTIONS is answered 204 either way.
- X-Accel-Buffering: no on SSE stays. origins_of() checks both lists at start (scheme://host[:port], no paths;
"*" only for cors_origins). docs/DETAILS.md; tests for the bypasses, the trusted origin, CORS off/on, the header.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds support for web-based API clients (CORS) and reverse proxies / tunnels (such as Cloudflare Tunnel, Tailscale Funnel, and Nginx) when remotely serving Strata or connecting third-party web frontends.
Key Changes
CORS & Preflight (\OPTIONS\ 204 No Content):
Reverse Proxy Origin Validation:
SSE Stream Buffering (\X-Accel-Buffering: no):
Unit Tests:
Authored by @BlitzenCats & Gemini