Anchor jq validators at true string ends so malformed keys fail closed - #117
Merged
Merged
Conversation
thetangstr
force-pushed
the
fix/compose-up-strict-jq
branch
2 times, most recently
from
September 17, 2026 04:11
71803ab to
b015d89
Compare
jq regexes are Oniguruma, where $ anchors before a trailing newline, and $(...) strips trailing newlines — so a kid or secretBase64 with an escaped trailing newline could pass the wrapper and then fail the stricter JS validator inside the container. Anchor every pattern with \A...\z to bind true string ends, and keep the secretBase64 pattern strictly structural (alphabet + padding shape only). Canonicality — including nonzero pad bits, which a structural regex cannot detect — is proven by the original decode-and-reencode equality check, now safe because the pattern already excludes whitespace from the extracted value. Same \A\z hardening applied to the release-pin filter. Constraint: systemd PATH provides jq and coreutils only — no node Rejected: derive canonicality from the structural regex alone | nonzero pad bits match the pattern but never round-trip, weakening the old validator's exact semantics Confidence: high Scope-risk: narrow Directive: never use $ anchors in jq test() for security-relevant patterns — always \A...\z; and never let a structural regex stand in for a canonicality proof Tested: infra suite 29/29 incl. escaped-trailing-newline kid and secretBase64, a noncanonical pad-bit variant, and a newline-suffixed release pin, all rejected before docker; git diff --check clean Not-tested: live systemd run on the production box
thetangstr
force-pushed
the
fix/compose-up-strict-jq
branch
from
September 17, 2026 04:13
b015d89 to
4eb6aa8
Compare
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
node-free validator: jq'stest()uses Oniguruma, where$anchors before a trailing newline, and$(...)strips trailing newlines — so akidorsecretBase64with an escaped trailing\ncould pass the wrapper while the container's stricter JS validator rejects it, deferring failure to container startup.\A...\z(true string ends), in both the runtime-key filter and the release-pin filter.secretBase64gets a strict structural pattern (alphabet + padding shape), which also guarantees the extracted value contains no whitespace for$(...)to strip — making the originalbase64 -d | base64decode-and-reencode equality check safe to run again. Nonzero pad bits (e.g....ZWV=) still fail exactly as the oldnodevalidator rejected them.dockeris invoked: escaped trailing newline inkid, escaped trailing newline insecretBase64, a noncanonical pad-bit variant at valid apparent length, and a trailing-newlinesourceCommitin the release pin (therelease_filtergot the same\\A\\zhardening).Test plan
node --test infra/test/deploy-assets.test.mjs— 29/29, including all new rejection cases (asserted: nonzero exit, docker never invoked)npm test— 625 workspace + 36 infra, 0 failnpm run build,git diff --checkcleanGenerated with Devin