A capability token with a line break inside it is printed in the job log #51
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
When
REVIEW_CAPABILITY_TOKENholds a carriage return or line feed inside its value, the wrapper prints the whole token to stderr after 40 seconds of retries, and no request ever reaches the service.What happens
reviewCredentials()returns the token without checking its shape (src/credentials.ts:69). The runtime then refuses to build theAuthorizationheader, and its error message quotes the header value. The retry ladder copies that message into its failure text (src/review/session.ts:121-124), and the orchestrator writes it to stderr (src/wrapper/orchestrator.ts:153-155).Reproduced at
9f272a52with the committed bundle on Node 24.21.0, the runtimeaction.ymldeclares. A token ofFAKECAP-AAAA\r\nFAKECAP-BBBBwas printed in full, 40 seconds after the start, with 0 requests sent to the service (scenarioss1-crlf,s1-lf-only,s1-cr-only). A line feed at the start of the value is printed too (s1-leading-lf), because it sits afterBearerin the header. A line break at the end of the value is not printed (s1-trailing-lf), and neither is trailing whitespace (s1-ws).What it should do instead
reviewCredentials()should reject a token that contains a character an HTTP header value cannot hold. The error should name the variable and the problem and never repeat the value. Failing there ends the run immediately, before the retry ladder.Why it matters
The capability token has no expiry (
src/review/session.ts:52), so a printed token stays valid until someone rotates it. If the real token is one of the lines of the stored value, that line is printed along with the rest.This needs an operator to store a malformed secret. A pull request cannot cause it. Whether the job log shows the value or masks it depends on the runner's secret masking, which has not been checked on the deployed runner.
🤖 Generated with Claude Code