Repository navigation
Harden the hosted worker: no operator-key fallback, browser-bound OAuth state - #37
Merged
Merged
Conversation
…th state - POST /mcp without an API-key header no longer runs tools with the SUPADATA_API_KEY worker secret, and OAuth Bearer requests no longer skip token validation through that branch. - The status tools encode the job id as a single path segment and refuse dot segments, so an id can't send the authenticated GET to another path. - /oauth/authorize sets a __Host- cookie with a random binding value stored next to the state; /oauth/callback requires it (constant-time compare) before it consumes the state. The dashboard also receives the client's redirect_uri so its consent screen can show where the grant goes. - The release job only runs on main and runs in a `release` environment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supadata-mcp | 0029e02 | Oct 25 2026, 08:16 PM |
The dashboard URL now carries sig = hex HMAC-SHA256(MCP_JWT_SECRET, state + "\n" + redirect_uri + "\n" + client), so the consent screen can verify the redirect host and client name it shows. Co-Authored-By: Claude Opus 5.5 <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.
Summary
src/worker.ts). If theSUPADATA_API_KEYworker secret was set, aPOST /mcpwith no API-key header ran every tool on that key. OAuth Bearer requests took the same branch, so their tokens were never validated. Header-less requests now always go through OAuth.CLAUDE.mdnow says the variable is for stdio only.src/mcp.ts). The three*_check_*_statustools put theidinto the URL without encoding it, so../x,x?y=1or..\xcould send the authenticated GET to another API path. Ids are nowencodeURIComponent-ed, and./..are refused.src/auth-handler.ts)./oauth/authorizestores a random binding value with the state and sets it in a__Host-mcp_auth_<state>cookie (HttpOnly, Secure, SameSite=Lax, 1 h)./oauth/callbackrequires that cookie (constant-time compare) before it consumes the state. A state someone else started can't be completed from a victim's browser. The dashboard redirect now also carriesredirect_uri(the client's registered redirect), so the consent screen can say where the grant goes. The flow itself is unchanged.publish.yml). The job hasif: github.ref == 'refs/heads/main'andenvironment: release.sig= hex HMAC-SHA256(MCP_JWT_SECRET,state\nredirect_uri\nclient), with client '' when absent. The dashboard can verify it before showing the redirect host and client name.Owner follow-up
release(created on the first run): restrict deployment branches tomain.release. Without this, a branch copy of the workflow still matches the publisher.wrangler secret delete SUPADATA_API_KEY).redirect_urihost on the MCP consent screen, and keep pinningcallbackto the worker origin.Tests
npm test(111 passed),tsc --noEmit, eslint clean. New tests: env key never used (with and without a Bearer token), job-id traversal cases for all three status tools, and a callback with a missing or forged binding cookie is refused without consuming the state.🤖 Generated with Claude Code