/** * Security Scanner — paste/snippet-host reputation + fetch-context escalation * @module @skillsmith/core/security/scanner/SecurityScanner.paste-host * * SMI-6033 Wave 3 (Gap 4 fix): the originally-shipped version of this * detector (commit b74c18436) implemented a SIMPLER, and in one specific way * INCORRECT, design relative to the approved plan * (docs/internal/implementation/smi-6033-clawhavoc-scanner-gaps.md, Gap 4): * it used a single flat PASTE_HOST_DOMAINS list (incorrectly including * transfer.sh/file.io alongside glot.io/pastebin.com) and treated ANY * same-line fetch of a paste-host URL as standalone-critical, with no * requirement that the fetched content actually be EXECUTED. This file fixes * both: * * 1. Two separate reputation tiers (patterns.ts): `ANON_PASTE_HOSTS` (+ * `URL_SHORTENER_DOMAINS`, execution-gated the same way) vs. * `TRANSIENT_TRANSFER_HOSTS` (never standalone-critical — a deliberate, * documented exception for legitimate debugging/incident-response * fetches of ephemeral reproducers). * 2. Execution evidence is now REQUIRED for `ANON_PASTE_HOSTS`/shorteners * to reach critical — either (a) the URL is piped directly to an * interpreter on the same line (`curl | bash`, no intermediate * file), (b) `npx ` directly executes the fetched content (no * pipe, no intermediate file either), or (c) the fetch destination is * subsequently executed/chmod'd/sourced ELSEWHERE in the content, * correlated via the shared `isCorrelatedWithFetchDestination` utility * (SecurityScanner.fetch-correlation.ts). Fetched-but-not-executed, or * merely linked, now correctly stays at the existing scanUrls() * `url`:medium finding — no new finding here. * * (a)/(b) are a NEW, local execution-detection shape distinct from (c): * `isCorrelatedWithFetchDestination` only detects "was this basename later * written as a fetch command's DOWNLOAD DESTINATION, then referenced * elsewhere" — it has no notion of a same-line direct pipe/direct-exec (no * intermediate file at all). The direct-pipe/npx-direct-exec patterns below * are local to this file (not promoted to the shared fetch-correlation * module, which Gap 5's concurrent xattr fix does not touch) and are * deliberately scoped to "the URL being piped/executed is specifically a * paste-host or shortener domain" — `CODE_EXECUTION_PATTERNS`' own curl|bash * pattern (patterns.ts) already fires independently for ANY curl|bash * regardless of domain reputation; this file adds the DOMAIN-REPUTATION-aware * escalation on top. * * `TRANSIENT_TRANSFER_HOSTS` never reaches critical: it emits * `paste_host_fetch` at medium whenever it is an actual fetch target (the URL * is the ARGUMENT of a same-line fetch verb — see `isActualFetchTarget` * below), regardless of execution evidence — `curl file.io/x | bash` alone * staying sub-threshold is intentional, not a gap (see patterns.ts's * `TRANSIENT_TRANSFER_HOSTS` comment for the rationale). * * SMI-6033 Wave 3 (adversarial-review fix): the "is this URL fetched?" gate * used to be a bare `FETCH_COMMAND_PATTERN` test against the whole LINE, so a * fetch verb ANYWHERE on the line counted — `curl --version; see mirror docs * at https://pastebin.com/abc` wrongly registered the pastebin URL as * fetched. Replaced with `isActualFetchTarget`, which binds the URL to the * verb by tokenizing the prefix that precedes it. Same bug class as Wave 4's * `decoy_misdirection` fix; see `isActualFetchTarget`'s own doc comment for * the two deliberate adaptations to this detector's inputs. This affects ONLY * the same-line fetch-target gate — the direct-pipe and npx-direct-exec * execution-evidence paths below are a different code path and are unchanged. * * Known, documented residual (static scanner, no network I/O): redirect- * chain/final-host resolution is out of scope by design — custom domains, * redirects, and compromised allowlisted hosts are a known residual. */ import type { SecurityFinding } from './types.js'; import type { LineContext } from './SecurityScanner.helpers.js'; export declare function scanPasteHostFetch(content: string, lineContexts?: LineContext[]): SecurityFinding[]; //# sourceMappingURL=SecurityScanner.paste-host.d.ts.map