fix: require API key authentication on /tabs/:tabId/evaluate endpoint#3087
Open
sebastiondev wants to merge 1 commit into
Open
fix: require API key authentication on /tabs/:tabId/evaluate endpoint#3087sebastiondev wants to merge 1 commit into
sebastiondev wants to merge 1 commit into
Conversation
The evaluate endpoint allows arbitrary JavaScript execution in the browser page context. Previously it had no authentication, meaning any network client could call it to execute JS in authenticated sessions (imported cookies), steal session tokens, or exfiltrate page data. This adds the same CAMOFOX_API_KEY / Bearer token check used by the cookie import endpoint, extracted into a reusable requireApiKey middleware. When CAMOFOX_API_KEY is set, a valid Bearer token is required. When unset, only loopback requests in non-production environments are allowed. CWE-94: Improper Control of Generation of Code (Code Injection)
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
The
POST /tabs/:tabId/evaluateendpoint accepts a user-suppliedexpressionstring and passes it directly to Playwright'spage.evaluate(), executing arbitrary JavaScript in the browser page context. Unlike the/sessions/:userId/cookiesendpoint (which requires a Bearer token viaCAMOFOX_API_KEY), the evaluate endpoint had no authentication, allowing any network-reachable attacker to run arbitrary JS in any open tab.CWE-94 — Improper Control of Generation of Code ("Code Injection")
Severity: High — an unauthenticated attacker with network access can exfiltrate cookies, localStorage, session tokens, and DOM content from authenticated browser sessions, or perform arbitrary same-origin actions.
Data flow
POST /tabs/:tabId/evaluatewith{ "expression": "document.cookie" }— no auth requiredserver.jspassesexpressiondirectly topage.evaluate(expression)(Playwright)What changed
server.js— Extracted a reusablerequireApiKeymiddleware (identical logic to the existing cookie-import auth check) and applied it to the/tabs/:tabId/evaluateroute. The middleware:Bearer <CAMOFOX_API_KEY>header when the API key is configured403 Forbiddenotherwisetests/unit/evaluate-auth.test.js— Three new integration tests verifying:Why this is exploitable
The README documents production deployment via Docker and Fly.io with secrets, meaning the server is internet-exposable. An attacker who can reach the server only needs a valid
tabId(a UUID, but discoverable via the unauthenticated tab listing endpoints) to execute arbitrary JavaScript. Combined with the authenticated cookie import feature, this means an attacker could exfiltrate session tokens from sites where cookies have been loaded.Before submitting, we considered whether existing mitigations would prevent exploitation — there is no reverse proxy auth requirement documented, no IP allowlisting, and the server binds to
0.0.0.0by default. The cookie endpoint already recognized this risk and added auth; the evaluate endpoint was simply missed.Test results
All 113 existing tests continue to pass. The 3 new auth tests validate the expected 403/200 behavior with and without valid credentials.
Submitted by Sebastion — autonomous open-source security research from Foundation Machines. Free for public repos via the Sebastion AI GitHub App.