Have any questions? +1 646.844.5712 (US)

  • Facebook
  • LinkedIn
  • Twitter
HiTech ServiceHiTech Service
  • Home
  • About
  • Services
    • Software Development
    • Customer Support
    • Quality Assurance
    • Managed Services
    • Compliance Audit
    • GDPR Compliance
    • Competency Center
    • Emergency IT Support
    • Software as medical device
    • Local AI Agent Development
  • Projects
  • GDPR
  • Articles
  • Case Studies
  • Contact
Menu
  • Home
  • About
  • Services
    • Software Development
    • Customer Support
    • Quality Assurance
    • Managed Services
    • Compliance Audit
    • GDPR Compliance
    • Competency Center
    • Emergency IT Support
    • Software as medical device
    • Local AI Agent Development
  • Projects
  • GDPR
  • Articles
  • Case Studies
  • Contact
Layered translucent panels inspected by magnifying glasses while a glowing shard slips through a gap between layers

When Config Became Executable: The Twenty-Year Pattern Behind Supply Chain Attacks

By Dmitriy

A developer clones a repository and opens the folder in their editor. Nothing else. No npm install, no build, no script anyone chose to run. The machine begins sweeping the disk for private keys.

That was one of the execution paths in the compromise of the keyv npm packages, and the part worth pausing on is where the code lived. Not in a package. The worm wrote a SessionStart entry into .claude/settings.json and a folderOpen task into .vscode/tasks.json, files that execute when the cloned folder is simply opened. Neither file is a package. Neither is scanned. Both run.

It reads like a new category of attack. It isn’t. Roughly every four years since the mid-2000s, some file that nobody classifies as code turns out to execute anyway — and the tooling built to inspect the previous generation of artifacts takes years to notice.

The artifact that isn’t in the repository

Three of the most-studied supply chain incidents share a structural signature so precise it should have become a checklist item years ago: the malicious thing was absent from the source repository and present only in what people actually ran.

Two abstract documents side by side, the right one containing an extra jagged amber line absent from the left

In 2018, the maintainer of event-stream handed publishing rights to a volunteer who asked for them politely. The malicious dependency that followed, flatmap-stream, carried an extra file that was not in the GitHub repository, AES256-encrypted using the parent package’s own npm_package_description field as the decryption key. It did nothing on a normal install. It fired inside one company’s release build script, targeting a Bitcoin wallet, and shipped in Copay 5.0.2 through 5.1.0. Anyone reading the repo saw clean code, because the repo was clean.

In 2020, attackers put an implant called SUNSPOT inside SolarWinds’ build server. It watched for MsBuild.exe, hijacked the build when it recognized Orion, and injected the SUNBURST backdoor into the output. Up to 18,000 customers installed the result. The update was correctly signed. The signature was honest — it certified that SolarWinds built the artifact, which SolarWinds had.

In 2024, the backdoor in xz utils depended on a build-to-host.m4 macro that existed only in the release tarball and not in the Git distribution. The second-stage payload sat in the repository disguised as test data, completely inert, waiting for a macro that only appeared downstream.

Different decades, different ecosystems, one mechanism. Review looks at the source. Execution happens somewhere else.

Why the scanner never had a chance

The uncomfortable finding isn’t that scanners missed these. It’s that scanners were structurally incapable of catching them.

Phoenix Security’s malware package corpus tracks the acceleration: 6 campaigns and 30 malicious packages in 2024, 14 campaigns and 111 packages in 2025, then 37 campaigns and 497 packages in the first half of 2026 alone. One month, May 2026, produced more indexed packages than the preceding four combined. npm accounts for 79.3% of the indicators; PyPI 9%; VS Code and OpenVSX extensions another 6.2%.

Buried in that dataset is the number that explains the whole problem. Across 59 documented campaigns, zero CVEs were assigned during active exploitation. Not few. Zero. CVE-feed scanners had no detection surface for 100% of them.

That is not a failure of diligence. A CVE describes a defect in code — a buffer that overflows, a parser that trusts input it shouldn’t. None of these attacks involved a defect. They involved a stolen maintainer account, a self-propagating worm, or a configuration file doing exactly what configuration files are designed to do. There is nothing to assign a number to, and no version range to flag as vulnerable, because the vulnerable version and the safe version are the same code published by different hands. Sonatype counted 454,600 new malicious packages across 2025, with quarterly growth of 188% year over year — a volume that no CVE process was ever meant to absorb.

We’ve written before about the gap between a patch shipping and agencies applying it. That gap at least assumes a patch exists. This is the other category — the one where there is no advisory to be late on.

The newest file that runs

Which brings us back to the file that starts executing when you open a folder.

An opening folder with keys, gears and a padlock escaping upward as fine particles

The pattern’s current instance began earlier in 2026 with a campaign researchers named TrapDoor: 34 packages across 384-plus versions, planted simultaneously on npm, PyPI and Crates.io, each with an execution path matched to its runtime — postinstall hooks, import-time fetch, a malicious build.rs. The novel component was the payload’s hiding place. The packages carried .cursorrules and CLAUDE.md files containing instructions written in zero-width Unicode characters: invisible to a human reading the file in an editor, fully legible to the AI coding assistant that reads the same file as project guidance. The hidden text instructed the assistant to run a "security scan" that exfiltrated SSH keys, AWS credentials, GitHub tokens and browser login databases. Some of these files arrived as pull requests with titles like docs: add .cursorrules with dev standards and build verification.

Then came the keyv compromise, which started, as these usually do, with a compromised GitHub maintainer account rather than any technical flaw. A malicious release reached more than 400 npm packages in roughly thirty minutes; one analysis put it above 440 packages and two thousand versions within hours. The payload pulled down a standalone Bun runtime and a 728 KB obfuscated second stage, harvested cloud metadata, Vault tokens, Kubernetes service-account tokens and CI secrets, then republished itself using the npm token it had just stolen. Its credential target list had grown about 70% over the previous variant, and the additions are telling: Claude, OpenAI, Cursor and Gemini API keys. Command-and-control domains were fetched from an Ethereum smart contract, so infrastructure could rotate without touching the malware.

One detail deserves to survive this particular incident. The worm installed a host-level watcher — a LaunchAgent on macOS, a systemd user service on Linux — that polled GitHub every 60 seconds with the stolen token. When the token stopped working, which is precisely what revoking it produces, the watcher evaluated an attacker-supplied handler string fetched from the network. The standard first move in incident response was itself the trigger. Isolating the host from the network had to come before rotating anything.

An arXiv study of 1.43 million agent skills recently described the ecosystem’s metadata layer as "activation-ready but governance-poor," with recursive reuse creating what the authors call a hidden package inventory — dependencies that exist in effect but appear in no manifest. That’s a familiar sentence with the nouns swapped. It could have been written about npm in 2015.

What actually holds

The defenses that work are the ones that stopped asking whether an artifact is malicious and started asking where it came from.

npm’s trusted publishing, wired to GitHub Actions or GitLab CI, generates SLSA Build Level 2 provenance signed through Sigstore with no extra configuration, letting a consumer verify that a package was built by the workflow in the repository it claims to come from. That’s real progress, and it’s worth stating its limit plainly: provenance proves origin, not intent. It would not have stopped event-stream, where the malicious release came from the legitimate publisher through the legitimate pipeline. Attestation raises the cost of impersonation. It does nothing about a maintainer who has been replaced.

The Codecov breach makes the second point. Attackers modified the Bash Uploader script to exfiltrate CI environment variables, and it ran undetected from January 31 to April 1 of 2021 across more than 23,000 customers — found not by a scanner but by a customer who noticed a checksum mismatch between the script on GitHub and the one they’d downloaded. Verifying the hash of anything your pipeline fetches at runtime is unglamorous and remains one of the highest-yield controls available.

The third is new, and cheap, and almost nobody does it yet: treat agent instruction files as reviewable code. .claude/, .cursorrules, .vscode/tasks.json, and whatever the next editor introduces belong in code review with the same scrutiny as a shell script, because functionally that is what they are. Screen them for invisible Unicode. Treat a docs:-prefixed commit that adds one as a change to the build. The convention that these files are documentation is a convention, and the last two years have established that attackers do not share it.

None of this is exotic. It’s the same set of controls that has always applied when developer machines and build pipelines hold the credentials — which is why credential exposure through developer and account compromise keeps showing up as the actual root cause, and why pipeline and test automation hygiene is a security control and not just an engineering-quality one.

The question worth carrying forward

The useful lesson from twenty years of this is not "watch out for agent config files." That’s the specific answer to the last attack, and specific answers to last attacks are how the industry got here.

The lesson is the shape. Every generation of tooling inspects the artifact that the previous generation was exploited through, and attackers move one layer down to whatever the tooling has classified as inert. Antivirus watched binaries, so the payload moved into packages. Dependency scanning watched packages, so it moved into install hooks and build scripts that run before anything is declared. Now scanners read lockfiles and postinstall scripts, and it has moved into a plain-text file that no scanner classifies as code at all.

The question to ask about your own repository is not whether it contains a known-bad file. It’s which file in it currently executes without anyone calling it code.

  • On August 10, 2026
  • 0 Comment
Tags: AI, cybersecurity, DevOps, npm, supply chain, vulnerability management

Leave Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts
  • The Password Memo Was Honest. The Checklist Wasn’t.
  • As Is: How Software Became the Only Product You Could Legally Sell Broken
  • The Production Incident Class Your Postmortem Template Doesn’t Have
  • Why Load Test Numbers Lie
  • When Config Became Executable: The Twenty-Year Pattern Behind Supply Chain Attacks
Categories
  • ai (8)
  • android (18)
  • apple (36)
  • chart (18)
  • cloud (1)
  • fix (42)
  • games (11)
  • google (31)
  • hardware (73)
  • healthcare (3)
  • how to (231)
  • internet (92)
  • ios (23)
  • macos (3)
  • microsoft (82)
  • mobile (36)
  • news (74)
  • optimization (17)
  • osx (4)
  • outsourcing (8)
  • qa (3)
  • regulation (7)
  • review (120)
  • security (40)
  • software (160)
  • windows (150)
Archives
  • August 2026
  • July 2026
  • June 2026
  • May 2026
  • August 2025
  • March 2025
  • February 2025
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • March 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • June 2018
  • May 2018
  • April 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • July 2015
  • January 2015
Archives
  • August 2026
  • July 2026
  • June 2026
  • May 2026
  • August 2025
  • March 2025
  • February 2025
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • March 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • June 2018
  • May 2018
  • April 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • July 2015
  • January 2015

How Software Became a Medical Device

Previous thumb

Why Load Test Numbers Lie

Next thumb
Scroll

Services

  • Software Development
  • Quality Assurance
  • Customer Support
  • Managed Services
  • 24/7 Emergency IT Support
  • Competency Center
  • Local AI Agent Development
  • Software as a Medical Device

Compliance

  • Compliance Audit
  • GDPR Compliance
  • What is GDPR
  • ISO 9001:2015 Certification

Company

  • About Us
  • All Services
  • Projects
  • Case Studies
  • Articles
  • Contact
About HiTech Service

With 10 year experience of working together, we have reached tangible synergetic effect in performance and productivity, which results in highest quality services and satisfied clients.

Privacy Policy   Cookie Policy

 

  • Facebook
  • X
  • LinkedIn
CONTACT INFO
  • 900 Foulk Rd, Suite 201, Wilmington, DE, USA, 19803
  • Kudryavs’kyi descent 5b, Kyiv, Ukraine, 04053
  • +1 646.844.5712 (US)
ISO 9001:2015 certificate issued to HiTech Service LLC by Veritas
RIPE Atlas logo, the network measurement community HiTech Service takes part in
BrainBasket Foundation logo, IT education initiative HiTech Service supports
HiTech Service LLC membership badge of the Hi-Tech Office Ukraine association Dun & Bradstreet verified business badge for HiTech Service LLC
YouTeam partner badge for HiTech Service LLC
Hitech Service LLC

Copyright 2026