Repository navigation
fix(security): refuse cross-site calls, gate debug routes, drop the netlog recorder - #81
Merged
Merged
Conversation
…etlog recorder The agent API has no auth and trusted any caller that could reach 127.0.0.1, which includes every web page open in the browser. - Requests are refused when their Origin is not localhost / 127.0.0.1 / [::1] or the extension, when an Origin-less request says Sec-Fetch-Site: cross-site, or when Host is not a local name (DNS rebinding; FLOWKIT_ALLOWED_HOSTS adds more). CORS is limited to the same origins instead of "*". - Debug routes (eval-tab, test-*, stream-chat, submit-ui-prompt, find-actions, media-url, reload*, debug-tab, /api/flow/debug-*, /api/test-direct) answer 404 unless FLOWKIT_DEBUG_ENDPOINTS=1. - The "temporary" webRequest netlog recorder is removed from the extension (0.5.3) along with /api/ext/netlog. It logged every flow.google.com request body, including the session's `at` token, to a file any web page could read back. - /api/ext/callback checks the X-Callback-Secret the extension already sends; the extension falls back to the WebSocket if it is rejected. - The extension WebSocket server and /ws/dashboard accept only the extension / exact local origins (the dashboard check matched http://localhost.evil.example). - StreamChat (CHAT_GENERATION) now shares the generation throttle and unusual-activity hold. - Operation poll caches evict their oldest entries instead of being cleared wholesale at 512; the media and poll caches were unbounded. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
The agent API has no auth: it trusted any caller that could reach
127.0.0.1:8100, and every web page open in the browser can. With CORS*, an unauthenticated/api/ext/eval-tab(arbitrary JS in the signed-in Flow tab) and a netlog recorder that stored every Flow request body — including the session'sattoken — behind an openGET /api/ext/netlog, any site could act in or read from the user's Flow session.Changes
Originis not localhost /127.0.0.1/[::1](any port) orchrome-extension://<id>, Origin-less requests markedSec-Fetch-Site: cross-site, and anyHostthat is not a local name (DNS rebinding;FLOWKIT_ALLOWED_HOSTSadds names, e.g. a tunnel). CORS limited to the same origins.FLOWKIT_DEBUG_ENDPOINTS=1(404 otherwise):eval-tab,test-*,stream-chat,submit-ui-prompt,find-actions,media-url,reload*,debug-tab,/api/flow/debug-*,/api/test-direct.docs/CAPTURE.mdkeeps the throwaway recipe with a warning never to ship it./api/ext/callback(the extension already sent it; the server never checked). The extension falls back to the WebSocket if the callback is rejected.:9222) accepts onlychrome-extension://or no Origin;/ws/dashboarduses the exact local-origin match (it acceptedhttp://localhost.evil.example).CHAT_GENERATION) now goes through the generation throttle and unusual-activity hold from fix(flow): keep the unusual-activity hold across restarts, bound hijack retries #75.Upgrade: reload the extension in
chrome://extensionsafter pulling. Extension 0.5.2 keeps working against this agent (it already sends the secret).Test plan:
pytest -q tests: 507 passed (newtests/unit/test_api_security.py: cross-site/Host refusals, local callers pass, CORS, debug gate on/off, netlog gone, callback secret, dashboard WS lookalike origin; throttle tests for StreamChat hold and cache eviction)node tests/extension_mv3_bootstrap.test.cjspasses (it failed before: its chrome stub had nowebRequest.onBeforeRequest)/api/ext/tabsround-trips through the secret-checked callback (200);Origin: https://evil.example→ 403;Host: evil.example→ 403; debug routes → 404localhost:5173origin test)🤖 Generated with Claude Code