NodeSecure / NodeSecure/scanner

(Scanner) new re-enforced supply-chain detection following axios

Open
#707 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
40
Forks
23
Avg merge
23h 23m
Merged PRs (30d)
2

Description

The recent axios supply chain attack exposed a gap in NodeSecure's detection capabilities. The malicious package plain-crypto-js@4.2.1 — a doppelganger of the legitimate crypto-js — was injected as a phantom dependency into axios@1.14.1 and axios@0.30.4, dropped a cross-platform RAT via a postinstall script, and self-destructed after execution. NodeSecure failed to flag this package as suspicious.

This issue proposes a new Package Integrity Security Layer to detect such attacks proactively.

Background

The attack leveraged several techniques that should be detectable:

  • Phantom dependency injection: plain-crypto-js appeared in package.json but was never imported anywhere in the axios source code.
  • postinstall script as dropper: the entire malicious payload was triggered via a postinstall hook in an injected dependency.
  • Doppelganger package: plain-crypto-js cloned the name, description, author, and repository URL of the legitimate crypto-js package, differing only in the name field and the added postinstall script.
  • Version spoofing: after execution, package.json was replaced with a clean stub reporting a different version (4.2.0) to evade post-infection audits.
  • Trusted Publisher bypass: the malicious axios versions were published manually via a stolen token, breaking the established OIDC Trusted Publisher pattern used by all legitimate releases.

Proposed Detection Layer

Trigger Conditions

A package should be flagged for deeper inspection when one or more of the following conditions are met:

  • postinstall (or other lifecycle) script is present in package.json
  • Phantom dependency: the package appears in dependencies but has zero require()/import usages in the source tree
Validation Steps (when a package is flagged)

Once a package is flagged, the following checks should be performed:

  1. Remote package.json name verification
    Fetch the package.json from the declared GitHub repository (via the repository field) and assert that the name field matches the npm package name. A mismatch (e.g. npm name plain-crypto-js pointing to the brix/crypto-js repo) is a strong signal of a doppelganger.

  2. Downgrade / version integrity policy
    Cross-reference the installed version against the previous versions of the package on the registry. Verify:

    • Whether the publish method changed (e.g. OIDC Trusted Publisher → manual token)
    • Whether the gitHead field is absent (no corresponding Git commit/tag)
    • Whether the postinstall script is new relative to the previous version (regression check)
    • Optionally: check npm attestations/provenance for the package

Expected Outcome

When this layer detects a flagged package, NodeSecure should:

  • Emit a warning or error identifying the specific trigger condition(s)
  • Report the result of the remote name verification
  • Report any version integrity anomalies

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the package.json and source-tree dependency analysis entry points in the scanner, then review how lifecycle scripts and imports are currently represented. Define the implementation boundary for the two trigger conditions before evaluating remote repository metadata and version history. Done means flagged packages produce warnings or errors naming triggers and report name and version-integrity results.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, typescript
Domain
cli, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.