Skip to content

feat: Add typosquat-target detection to terminal-security package-manager rule - #12727

Open
mvanhorn wants to merge 3 commits into
continuedev:mainfrom
mvanhorn:fix/12573-terminal-security-typosquat-detection
Open

mvanhorn wants to merge 3 commits into
continuedev:mainfrom
mvanhorn:fix/12573-terminal-security-typosquat-detection

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The @continuedev/terminal-security package already recognizes package-manager install commands (npm/yarn/pnpm install/add) via isHighRiskPackageManager and routes them to allowedWithPermission, but it only answers 'is this an install?' not 'what is being installed?'. A command like npm install lodahs (one edit away from lodash) is treated identically to a legitimate install, with no typosquat signal for the reviewer.

Changes

Extend evaluateTerminalCommandSecurity.ts to parse the target package name(s) out of recognized install/runner commands and compare each against a small bundled allowlist of popular packages using an edit-distance (Levenshtein <= 1-2, excluding exact matches) heuristic. Add npx/bunx/pnpm dlx/yarn dlx runner forms to the set of commands whose first non-flag argument is treated as a package target. When a near-miss is detected, attach a structured typosquat warning to the existing evaluation result (new optional field on the result type in types.ts) and ensure such commands stay at allowedWithPermission rather than silently auto-running, surfacing the suspected canonical name. Keep the allowlist and distance logic self-contained so it remains offline and dependency-free, matching the existing rule style in this file.

Fixes #12573


Summary by cubic

Add typosquat-target detection to @continuedev/terminal-security package-manager rule to flag suspicious install/runner targets and keep them permission-gated. Fixes #12573.

  • New Features
    • Parse package targets from npm|yarn|pnpm install/add/i and runners npx, bunx, pnpm dlx, yarn dlx; check -p/--package (incl. --package=foo) as package targets and ignore non-package runner flags.
    • Detect near-miss names against a small bundled list of popular packages using bounded Levenshtein (<=2), skipping exact matches.
    • Attach typosquat-target warnings with packageName, suspectedPackageName, and distance; any warning forces at least allowedWithPermission.
    • Optional warnings via evaluateTerminalCommandSecurity(..., { includeWarnings: true }) or evaluateTerminalCommandSecurityDetailed; tests cover exact hits, typos, scoped/versions, runners and -p/--package cases, and negatives.

Written for commit f2197a2. Summary will update on new commits.

Review in cubic

@mvanhorn
mvanhorn requested a review from a team as a code owner June 17, 2026 14:48
@mvanhorn
mvanhorn requested review from sestinj and removed request for a team June 17, 2026 14:48
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 17, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/terminal-security/src/evaluateTerminalCommandSecurity.ts Outdated
The cubic review flagged that getRunnerPackageTargets put -p/--package in the
blind skip list, so a package specified via 'npx -p <pkg>' had its value
skipped and was never typosquat-checked. Move those flags out of
RUNNER_FLAGS_WITH_VALUES and capture their values (including --package=foo) as
package targets; with an explicit package flag the trailing positional is the
binary to run, not a package. Non-package flags (-c, --registry, etc.) are
still skipped. Adds tests for both cases.
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jun 18, 2026
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Both open points here are stale, so a re-run should clear this.

cubic's P2 on getRunnerPackageTargets: already fixed. cubic reviewed 7082690; the fix landed the next day in f2197a2, which handles -p/--package before the generic skip-flag-value branch and captures the value as a typosquat candidate instead of stepping over it. Covered by the "should warn for runner package flags that look like typosquats" case for npx -p expres cowsay, npx --package expres cowsay, npx --package=expres cowsay, and pnpm dlx --package expres cowsay. 232/232 pass in packages/terminal-security locally.

On jetbrains-tests: the failure is Autocomplete > testAutocomplete(), a headless-IDE integration test. This PR touches only three files under packages/terminal-security/ (a pure TS evaluator, its types, and its test), so there is no path from this diff to that test. The run is also from June 18.

Could someone re-run the checks? Happy to rebase onto current main first if that is easier.

`npm install lodash@npm:lodahs` installs lodahs, but the version strip cut
at the first @ and checked lodash. Read the target after @npm: instead.

This branch has not been deployed

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

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

terminal-security: package-manager rule flags installs but not typosquat targets (e.g. npm install lodahs)

1 participant