Skip to content

COR-1646: distinct malicious verdict at install time (npm/pip)#126

Open
juangaitanv wants to merge 5 commits into
mainfrom
juan/cor-1646
Open

COR-1646: distinct malicious verdict at install time (npm/pip)#126
juangaitanv wants to merge 5 commits into
mainfrom
juan/cor-1646

Conversation

@juangaitanv

Copy link
Copy Markdown
Contributor

COR-1646: Distinct malicious verdict at install time (npm/pip)

Known-malicious packages already blocked at install time, but were folded into the generic vulnerable verdict. This surfaces them as a distinct, blocking malicious signal on the corgea npm / corgea pip wrappers (yarn/pnpm/uv inherit via the shared precheck path).

What changed

  • New VerdictStatus::Malicious (src/precheck/mod.rs), separate from Vulnerable, carrying all matches.
  • Classifier VulnMatch::is_malicious() = malware flag OR advisory_id starts with MAL- (src/vuln_api/mod.rs). The MAL- prefix keeps the label correct even if this CLI ships before the worker that sets the authoritative flag.
  • BlockReason::Malware with top precedence and a distinct refusal (src/precheck/verdict.rs, render.rs):
    Refusing to run install: known MALICIOUS package(s) detected. Pass --force only if you are certain.
  • Render: known malicious: headline in both named and tree arms; separate malicious counts in the text summary (omitted when zero).
  • --json: new "status": "malicious", per-match "malware" boolean, and a malicious count in each summary object. schema_version stays 1 (purely additive).
  • --force overrides the malicious block unchanged and propagates the package manager's exit code.
  • Refreshed --force help (src/main.rs) and skills/corgea/SKILL.md copy; swept generic-vulnerable test fixtures off MAL- ids to CVE- so they stay Vulnerable under the new prefix rule.

Testing

  • cargo build --release
  • cargo test ✓ — all suites green (0 failed); +9 new tests: distinct malicious block + exit, --force override, mixed CVE+MAL tally, malicious-in-tree path, and a guard that a merely-vulnerable run's output never contains the string "malicious".
  • cargo clippy --all-targets -- -D warnings ✓, cargo fmt --check

Pre-existing cargo audit advisories (transitive quick-xml, git2) are unrelated — this diff touches no Cargo.toml/Cargo.lock.

Acceptance (COR-1646)

  • Distinct Malicious verdict, separate from Vulnerable, with its own message
  • corgea npm / corgea pip block a known-malicious version with a distinct message + non-zero exit
  • --force overrides
  • A merely-vulnerable package is never labeled malicious

Depends on the vuln-api change (Corgea/vuln-api, COR-1646) that emits the authoritative malware flag from /check; the MAL- prefix fallback means this CLI is correct regardless of deploy order.

Linear: COR-1646 · Parent: COR-1632 (POL-01)

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Finding: src/verify_deps/registry.rs:535 — CI rust-tests is currently red. Evidence: the GitHub job failed with -D clippy::question-mark on lines 535-540 (this block may be rewritten with the ? operator) and exited 101, while the PR body says clippy passed. Impact: this branch cannot be merged/released with required checks failing, independent of the install-verdict behavior. Fix: apply the clippy suggestion at that block (use let r = suffix.strip_prefix('c')?; for the final fallback) or otherwise make ./harness ci pass on the PR branch.

Open in Web View Automation 

Sent by Cursor Automation: pr-flow

Comment thread src/precheck/render.rs
Comment thread src/precheck/render.rs
New VerdictStatus::Malicious and BlockReason::Malware for install-time malware detection.
- Malicious classifier: malware flag OR MAL- prefix match
- Malicious counts in vulnerability aggregation
- JSON schema adds "malicious" field (schema_version unchanged)
- Tests + MAL- → CVE fixture sweep
Drop the MAL- prefix fallback from VulnMatch::is_malicious(). Live /check
reports the GHSA canonical alias as advisory_id (worker.js: canonical_alias
|| advisory_id), not the MAL- id, so the prefix never fired for GHSA-aliased
malware — the server malware flag is the single reliable signal. The vuln-api
/check malware field is therefore required, and the worker must deploy with/
before the CLI (a pre-COR-1646 server has no flag -> malicious packages still
block as Vulnerable, fail-safe, just unlabelled).

Update the classifier tests to the real contract: a malicious /check match
carries a GHSA advisory_id + malware:true; a MAL- id without the flag now
stays Vulnerable.
PR #126 review (render.rs:334): the shared Vulnerable|Malicious tree render
arm printed the `fix with:` upgrade hint, and verdict_json emitted a
`remediation` version, for a pre-existing malicious dep. A mixed CVE+MAL
payload could surface the CVE's advertised fix, steering toward installing
another version of a malicious package instead of removing it. Suppress both
for Malicious verdicts.

Tests: render unit test (malicious verdict_json remediation is null) and a
mixed CVE+MAL bare-install tree E2E (no `fix with:`, JSON remediation null).
Comment thread src/precheck/render.rs
Comment thread skills/corgea/SKILL.md Outdated
@juangaitanv
juangaitanv requested a review from leenk7991 July 16, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants