fix(gateguard): ignore heredoc prose for tee and path-qualified sinks (#2886)

Expand proven-passive heredoc recognition beyond bare `cat` so documentation
writes via `tee`, `/bin/cat`, and `command cat` no longer trip the destructive
command detector on body text, while still failing closed for shells and pipes.
This commit is contained in:
Frank_zhu
2026-09-17 17:29:26 +00:00
parent bb1c58a350
commit 7cfc9b3608
2 changed files with 92 additions and 4 deletions
+11 -4
View File
@@ -3,16 +3,23 @@
const { extractCommandSubstitutions } = require('../lib/shell-substitution');
/**
* Recognize the deliberately narrow passive sink supported by this parser.
* Shell operators and substitutions make the payload's destination ambiguous,
* so every other form retains the original input for fail-closed checks.
* Recognize proven-passive sinks whose heredoc payload is data, not a command
* stream. `cat` and `tee` (optionally path-qualified, or wrapped in
* `command`/`builtin`/`env`) only write stdin; they do not execute the body.
* Shell operators or substitution markers make the destination ambiguous, so
* every other form retains the original input for fail-closed checks.
*
* @param {string} line
* @returns {boolean}
*/
function isProvenPassiveHeredocLine(line) {
const trimmed = line.trim();
return /^cat(?=\s|[<>])/.test(trimmed) && !/[;&|()`]/.test(trimmed);
// Fail closed on control operators / grouping / command substitutions.
if (/[;&|()`]/.test(trimmed)) return false;
// Optional wrapper + optional path prefix + cat|tee, then args or redirect.
return /^(?:(?:command|builtin|env)\s+)?(?:(?:\.\/|\/(?:[\w.+-]+\/)*)?(?:cat|tee))(?=\s|[<>])/.test(
trimmed
);
}
/**