Repository navigation
fix(proxy): proxy.php refuses to run open, constant-length token compare, negative max_tokens - #1
Merged
Merged
Conversation
…es of the token compare proxy.php lives in public_html, so with no COUNTERSIGN_TOKEN anyone who found the URL could spend the operator's API key. It now answers 500 until a token is set, unless ALLOW_NO_TOKEN=1 says the directory is access-controlled some other way, matching proxy.js and engine.js, which refuse a public bind without a token. hash_equals() returns early on a length mismatch, so the token's length leaked through timing, contrary to what the README says. Both sides are now hashed first.
proxy.js and engine /proxy forwarded max_tokens: -5 as-is, which the API rejects; proxy.php already treated anything below 1 as missing.
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.
What
proxy.php fails closed without a team token.
proxy.phpis meant to sit inpublic_html, so withCOUNTERSIGN_TOKENunset anyone who found the URL could send requests on the operator's Anthropic key. Nothing stopped this except a "strongly recommended" line in the README. It now answers500 Server not configured: set COUNTERSIGN_TOKEN …until a token is set.ALLOW_NO_TOKEN=1turns that off for a directory that already has its own access control. This works the same way asproxy.jsandengine.js, which won't bind to a public address without a token.The PHP token compare no longer leaks the token's length.
hash_equals()returns early when the lengths differ, even though the README says "neither the token nor its length leaks through timing". Both sides are now hashed with SHA-256 before the compare, which is what the Node servers already do.A negative
max_tokensnow falls back to the cap.proxy.jsand the engine's/proxypassedmax_tokens: -5straight through, and the API rejects that.proxy.phpalready treated anything below 1 as missing.Behaviour change
If an existing PHP deployment has no token set, it will start returning a 500 with a message that names the fix. The README setup steps and troubleshooting table now cover this.
Tests
node test/servers.js: 111/111 with PHP 8.4 + curl, up from 106. The new checks are proxy.php refusing to forward without a token,ALLOW_NO_TOKEN=1overriding that, and all three servers capping a negativemax_tokens. Three of the new checks fail onmain.node eval/run.js: PASS, unchanged.e2e(Playwright 1.63.0, Chromium): 722/722 checks, 91 tests.index.htmlis untouched.