Commit a244850
committed
fix(core): extend substitution audit log + dual-check stripped form (#4386 R4)
Round-4 audit-log consistency fixes from wenshao:
1. **Dual-check stripped form in audit predicate** — round 3's
`maybeLogSubstitutionBypass` only ran `detectCommandSubstitution`
on the raw command, but `buildShellExecWarnings` (the
confirmation-dialog warning helper extracted in round 3) checks
BOTH the raw and the `stripShellWrapper`-stripped forms. For
wrappers like `bash -c 'echo $(cat secret)'` the `$(` sits inside
the outer single quotes, so raw-check returns false but the inner
shell still expands the substitution. Result: dialog showed the
warning, audit log silently dropped it — exactly the wrapper
pattern an exfiltration attack would use. Refactored the helper
to extract a pure predicate `shouldAuditSubstitutionBypass` that
does the dual-check, exported for unit testing.
2. **JSDoc correction** — round 3's JSDoc claimed "DEBUG-level log
here so the signal exists when `DEBUG=*` is set". Both clauses
were wrong: the call uses `debugLogger.warn` (WARN level), and
`debugLogger` is controlled by `QWEN_DEBUG_LOG_FILE` (active by
default) rather than the `DEBUG=*` convention of the `debug` npm
package. Rewrote the doc to match the real semantics.
3. **Audit log on three more auto-approve bypass paths** — round 3
only covered the YOLO and auto-mode-`approved` bypasses, missing
three other paths that auto-approve without invoking
`getConfirmationDetails()`:
- PM `'allow'` fast path (coreToolScheduler.ts:1664) — fires
when an allow rule matches a substitution-bearing command
(e.g. `allow Bash(python3 *)` + `python3 -c "$(...)"`).
- permission-request hook `shouldAllow` (line ~1896) — fires
when an external hook grants permission directly.
- `autoApproveCompatiblePendingTools` sibling-tool ProceedAlways
(line ~3300) — fires when one tool's user-issued ProceedAlways
outcome rolls up to a sister tool. Uses `canonicalToolName`
to normalise the legacy name in the audit log.
New `SubstitutionBypassReason` discriminator union surfaces the
bypass path in the log so operators can distinguish them.
4. **Unit test coverage** — added a `shouldAuditSubstitutionBypass`
describe block to `coreToolScheduler.test.ts` covering all 8
branches: non-shell tool, missing args, non-string command,
absent substitution, direct substitution (shell + monitor), the
load-bearing wrapper case (proves the dual-check works), backtick
substitution, and env-prefix substitution.
Out of scope: reviewer also suggested forcing `'ask'` whenever
substitution is detected with a matching allow rule. Declined —
would partially re-introduce #4093 (substitution can't be allowed
via rules even with explicit user intent), and overrides the
allow-rule "trust this pattern" semantics. The audit-log extension
above gives operators the visibility they asked for without
overriding user-configured permission policy.
Closes wenshao R4 findings: dual-check (cids 3293074365, 3293075616),
JSDoc level/envvar (cids 3293074371, 3293075619), audit on PM-allow
(cid 3293078740 — partial), audit on hook + sibling-auto (rid 4351040390
non-diff), and test coverage for the predicate (cid 3293078758 — partial).1 parent 42debd1 commit a244850
2 files changed
Lines changed: 158 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
41 | 42 | | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
8361 | 8363 | | |
8362 | 8364 | | |
8363 | 8365 | | |
| 8366 | + | |
| 8367 | + | |
| 8368 | + | |
| 8369 | + | |
| 8370 | + | |
| 8371 | + | |
| 8372 | + | |
| 8373 | + | |
| 8374 | + | |
| 8375 | + | |
| 8376 | + | |
| 8377 | + | |
| 8378 | + | |
| 8379 | + | |
| 8380 | + | |
| 8381 | + | |
| 8382 | + | |
| 8383 | + | |
| 8384 | + | |
| 8385 | + | |
| 8386 | + | |
| 8387 | + | |
| 8388 | + | |
| 8389 | + | |
| 8390 | + | |
| 8391 | + | |
| 8392 | + | |
| 8393 | + | |
| 8394 | + | |
| 8395 | + | |
| 8396 | + | |
| 8397 | + | |
| 8398 | + | |
| 8399 | + | |
| 8400 | + | |
| 8401 | + | |
| 8402 | + | |
| 8403 | + | |
| 8404 | + | |
| 8405 | + | |
| 8406 | + | |
| 8407 | + | |
| 8408 | + | |
| 8409 | + | |
| 8410 | + | |
| 8411 | + | |
| 8412 | + | |
| 8413 | + | |
| 8414 | + | |
| 8415 | + | |
| 8416 | + | |
| 8417 | + | |
| 8418 | + | |
| 8419 | + | |
| 8420 | + | |
| 8421 | + | |
| 8422 | + | |
| 8423 | + | |
| 8424 | + | |
| 8425 | + | |
| 8426 | + | |
| 8427 | + | |
| 8428 | + | |
| 8429 | + | |
| 8430 | + | |
| 8431 | + | |
| 8432 | + | |
| 8433 | + | |
| 8434 | + | |
| 8435 | + | |
| 8436 | + | |
| 8437 | + | |
| 8438 | + | |
| 8439 | + | |
| 8440 | + | |
| 8441 | + | |
| 8442 | + | |
| 8443 | + | |
| 8444 | + | |
| 8445 | + | |
| 8446 | + | |
| 8447 | + | |
| 8448 | + | |
| 8449 | + | |
| 8450 | + | |
| 8451 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
790 | 790 | | |
791 | 791 | | |
792 | 792 | | |
793 | | - | |
794 | | - | |
795 | | - | |
796 | | - | |
797 | | - | |
798 | | - | |
799 | | - | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
800 | 802 | | |
801 | 803 | | |
802 | 804 | | |
803 | 805 | | |
804 | 806 | | |
805 | 807 | | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
806 | 842 | | |
807 | 843 | | |
808 | 844 | | |
809 | 845 | | |
810 | | - | |
| 846 | + | |
811 | 847 | | |
812 | | - | |
813 | | - | |
814 | | - | |
| 848 | + | |
| 849 | + | |
815 | 850 | | |
816 | 851 | | |
817 | 852 | | |
| |||
1676 | 1711 | | |
1677 | 1712 | | |
1678 | 1713 | | |
| 1714 | + | |
| 1715 | + | |
| 1716 | + | |
| 1717 | + | |
| 1718 | + | |
| 1719 | + | |
1679 | 1720 | | |
1680 | 1721 | | |
1681 | 1722 | | |
| |||
1904 | 1945 | | |
1905 | 1946 | | |
1906 | 1947 | | |
| 1948 | + | |
| 1949 | + | |
| 1950 | + | |
| 1951 | + | |
| 1952 | + | |
| 1953 | + | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
1907 | 1960 | | |
1908 | 1961 | | |
1909 | 1962 | | |
| |||
3295 | 3348 | | |
3296 | 3349 | | |
3297 | 3350 | | |
| 3351 | + | |
| 3352 | + | |
| 3353 | + | |
| 3354 | + | |
| 3355 | + | |
| 3356 | + | |
3298 | 3357 | | |
3299 | 3358 | | |
3300 | 3359 | | |
| |||
0 commit comments