Commit 553a3d0
authored
Grep results bypass the secret scrub entirely (CL-5717) (#426)
* Add a failing test for grep output bypassing the secret scrub
ripgrepPlugin answers grep and search_files without calling next(),
so a secret-shaped string in grep output never reaches
toolResultSecretScrubPlugin, which sits later in the plugin array
(CL-5717). This test proves it: a grep hit on an AWS key and an
OpenAI-style key comes back unredacted through the real posix tool
chain.
* Prepend the secret scrub and result cap so short-circuiting plugins can't skip them
composeMiddleware wraps outer-to-inner in array order, so a plugin
positioned earlier in buildCorePosixToolPlugins still sees a call's
final result even when a later plugin (ripgrepPlugin) answers
directly without invoking its own next(). Move
toolResultSecretScrubPlugin and resultTruncationPlugin to the front
of the array so both are unconditional outer wrappers around the
entire chain, mirroring how vendor/intx-inference/src/assembly.ts
hardcodes its size-cap transform as the first, mandatory element
rather than trusting every middleware author to call next().
This closes CL-5717: grep output (and anything else a future plugin
answers without delegating) is now capped and scrubbed regardless of
where in the chain it short-circuits.
* Delete ripgrepPlugin's own char-cap helper now that the wiring caps unconditionally
bounded() and its six call sites reapplied truncateToolResultContent
by hand because ripgrepPlugin answers grep/search_files without
calling next(), so the old in-chain result-truncation plugin never
saw its output. Now that resultTruncationPlugin (and the secret
scrub) wrap the whole chain unconditionally, this duplicate
application is dead weight — six call sites are six places to forget
a future change to the cap. Deleted rather than left alongside the
new wiring.
* Fix the exploitable prepend order and make the short-circuit test cover the real wiring
Scrub was prepended outermost so it ran on already-truncated content:
a secret straddling the character-cap boundary got cut mid-pattern,
the scrub's regex no longer matched the fragment, and a bare,
unredacted piece of the credential reached the model with no
redaction marker. Truncation now sits outermost (index 0) and the
scrub sits at index 1, so the scrub always sees the full,
untruncated content — truncating already-redacted text loses nothing
sensitive, so this direction is safe in both orders where the
reverse is not. Added a permanent regression test for a secret
straddling the boundary.
Also rewrote the 'short-circuiting plugin still gets capped and
scrubbed' test: it previously hand-composed the scrub and cap
middleware in a hardcoded order, so it passed unchanged against the
pre-fix wiring and gave no protection against a real reordering of
buildCorePosixToolPlugins's output. It now takes the actual array the
builder returns, splices a short-circuiting stand-in into
ripgrepPlugin's own slot, and composes that — so reordering the real
array fails the test.
* Correct the short-circuit test's comment to match what it actually guards
The comment claimed swapping the cap and scrub back would fail this
test. It does not: the secret sits at the front of a 90KB payload,
nowhere near the cap boundary, so cap-then-scrub still leaves the
whole key intact for the scrub to catch. This test guards the
PREPENDED POSITION of both terminal concerns (moving them away from
the front of the array fails it); the RELATIVE order between them is
guarded only by the boundary-straddle test. Leaving the old comment
in place risked a future engineer reading this test as redundant
coverage and deleting the straddle test, silently reopening the
exploit.1 parent 1fb2a4f commit 553a3d0
4 files changed
Lines changed: 171 additions & 23 deletions
File tree
- src
- agent
- plugins
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
295 | 296 | | |
296 | 297 | | |
297 | 298 | | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
298 | 436 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
39 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
40 | 59 | | |
41 | 60 | | |
42 | 61 | | |
| |||
47 | 66 | | |
48 | 67 | | |
49 | 68 | | |
| 69 | + | |
| 70 | + | |
50 | 71 | | |
51 | 72 | | |
52 | 73 | | |
| |||
65 | 86 | | |
66 | 87 | | |
67 | 88 | | |
68 | | - | |
69 | | - | |
70 | 89 | | |
71 | 90 | | |
72 | 91 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
13 | | - | |
14 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | 4 | | |
6 | 5 | | |
7 | 6 | | |
8 | 7 | | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
12 | | - | |
13 | 11 | | |
14 | 12 | | |
15 | 13 | | |
| |||
33 | 31 | | |
34 | 32 | | |
35 | 33 | | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | 34 | | |
45 | 35 | | |
46 | 36 | | |
| |||
114 | 104 | | |
115 | 105 | | |
116 | 106 | | |
117 | | - | |
| 107 | + | |
118 | 108 | | |
119 | 109 | | |
120 | 110 | | |
| |||
130 | 120 | | |
131 | 121 | | |
132 | 122 | | |
133 | | - | |
| 123 | + | |
134 | 124 | | |
135 | | - | |
| 125 | + | |
136 | 126 | | |
137 | 127 | | |
138 | 128 | | |
| |||
150 | 140 | | |
151 | 141 | | |
152 | 142 | | |
153 | | - | |
| 143 | + | |
154 | 144 | | |
155 | 145 | | |
156 | 146 | | |
| |||
166 | 156 | | |
167 | 157 | | |
168 | 158 | | |
169 | | - | |
| 159 | + | |
170 | 160 | | |
171 | | - | |
| 161 | + | |
172 | 162 | | |
173 | 163 | | |
174 | 164 | | |
| |||
0 commit comments