Repository navigation
Scan out-of-process values with the vocabulary but no watcher deadline - #1147
Conversation
A generated regex bakes its match timeout into the instance, so the out-of-process set is the same patterns rebuilt without one, and the record budget those callers were handed had no loop to protect. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
PR Summary by QodoRemove deadlines from out-of-process secret scans
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 90a86218c8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Compiled is ignored under NativeAOT, where this set is never built; elsewhere the interpreter | ||
| // would scan a recording several times slower than the generated code does. | ||
| static Regex WithoutMatchTimeout(Regex generated) => | ||
| new(generated.ToString(), generated.Options | RegexOptions.Compiled, Regex.InfiniteMatchTimeout); |
There was a problem hiding this comment.
Keep a guard on backtracking patterns
For an out-of-process value consisting of an opening quote followed by many repetitions of secret and then :\n without a closing quote, the delimiter gate admits JsonKeySecretRegex, whose adjacent greedy character-class repetitions retry partitions at every keyword occurrence and exhibit quadratic runtime. Rebuilding every pattern with Regex.InfiniteMatchTimeout allows a sufficiently large, untrusted recording value to pin the scanner indefinitely instead of terminating after the former 100 ms guard; retain a safety timeout or make these patterns linear/non-backtracking before removing it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed and kept a safety net in b8bf49e: the rebuilt set now carries a 30 s per-call deadline (OutOfProcessMatchTimeout) instead of none. Measured on the quote-less keyword run you describe, the JSON-key pattern grows roughly 4x per doubling (2K keywords 1.4 ms, 4K 5.7 ms, 8K 21 ms), so a multi-megabyte run would take minutes; the linear scans cost about 27 ns per char, so 16M chars finish in under half a second. ASuperLinearScan_StillMeetsItsDeadline_OnARebuiltSet pins that a rebuilt set still ends that case.
A quote-less run of keywords makes the JSON-key pattern quadratic, so a scan with no deadline could run for minutes on a few megabytes; thirty seconds is beyond any linear scan and still ends that one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
No GitHub issue and no Linear issue of its own — surfaced by kurrent-io/kcap-server#2042 (AI-3115)
What & why
SecretRedactor.RedactValueandIsSecretKeyexist so an out-of-process caller can scan a whole recording with the production vocabulary. The generated patterns carry a 100 ms match timeout and every call a one-second record budget, so those entries throw on any multi-megabyte value: a 6M-char tool result trips the env-var pattern on an M-series Mac, and 400K-char ones trip it on a loaded CI runner. The vocabulary now lives inSecretPatterns, built twice: the generated set keeps the watcher's deadline forRedactLine, and the same patterns rebuilt under a 30 s per-call deadline serve the out-of-process entries with an unlimited record budget. That deadline is a safety net, not a budget: the env-var scan costs about 27 ns per char, so 16M chars take under half a second, while the JSON-key pattern is quadratic on a quote-less run of keywords (2K keywords 1.4 ms, 4K 5.7 ms, 8K 21 ms) and would otherwise never return.Where to look
RedactLineis unchanged, including itsregex_timeoutloss marker. Its 100 ms deadline is tight for the 4 MB records that path admits: a delimiter-rich record above roughly 3.5 MB is loss-marked on fast hardware and smaller ones on a loaded laptop. Left as is here.Verification
RedactValue_ScansAMultiMegabyteValue_WithoutTheWatcherDeadlinefails on main withRegexMatchTimeoutExceptionafter ~220 ms and passes here;ASuperLinearScan_StillMeetsItsDeadline_OnARebuiltSetpins that a rebuilt set still ends the quadratic case.Capacitor.Cli.Tests.Unitis 4,777 total, 0 failed, 21 skipped, and a localdotnet publish -c Release(osx-arm64) built the native binary with no IL2026/IL3050 warnings.FixtureIntegrityTestswithsrc/cliat this branch: 65 passed; the previous pin failed fiveCommitted_fixtures_are_cleancases in CI and thehuge-bodiesones locally.🤖 Generated with Claude Code