Skip to content

harden(supply-chain): guard against plaintext-data false positives in install detection #141

Description

@thehoff

Background

Surfaced live during peer review of #139: feeding a peer-review prompt to `agy` that described the install-detect regexes (the text contained substrings like `/usr/bin/npm install foo` as documentation, not as commands) was misclassified by the supply-chain gate as a real install and blocked. The widened path-separator anchor added in #139 makes this class easier to hit:

`echo "/usr/bin/npm install foo"` — the gate now sees the path-separator before `npm` and the install verb after, classifies it as an install, and gates the harmless print statement against the cooldown / vetting machinery.

The fix in #139 closed a real attacker vector; this issue tracks the regression risk it introduced for non-command text.

Proposal

The detector should distinguish command text from string data inside another command. Three viable approaches, pick after spiking:

  1. Utility-prefix allowlist — `echo`, `printf`, `cat`, `grep`, `rg`, `fgrep`, `awk`, `sed` etc. consume their args as data. If the first head-token of the chain is in this set, skip install detection inside the chain.
  2. Token-position constraint — require the install verb to be at command-start (first non-flag, non-env-assignment token of a logical command), not anywhere in the text. Demands the shell-aware tokeniser from the sibling issue.
  3. Quote-context exclusion — once #SHELL-TOKENISER lands, install verbs inside a quoted string are data unless the outer command is `sh -c`/`bash -c` (then recurse).

Approach (3) is the principled fix but depends on the tokeniser issue. Approach (1) is a pragmatic bandaid that catches the common cases and can ship first.

Acceptance criteria

Negative tests pin: `echo "/usr/bin/npm install foo"` → 0 detections; `grep "/opt/bin/pip install" README.md` → 0; `printf '%s\n' "npm install lodash"` → 0. Positive tests (real abs-path installs) still detected. The 30+ existing tests still pass.

Out of scope

The quote-aware tokeniser itself — sibling issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions