Socket’s researchers caught the new trick on a fresh batch of Composer libraries this week. Eight Packagist packages shipped a post-install hook hidden inside package.json, the npm-flavored manifest most Composer maintainers and audit tools have no reason to open. A few lines of JavaScript pulled a Linux binary down from a GitHub Releases URL and ran it on the host. The same week, attackers hijacked the Laravel Lang localization packages and pushed credential-stealing malware through tampered version tags. The cybersecurity industry still scans the front door of the package registry while attackers stroll in through the contractor’s entrance.

The Wrong File Was the Whole Point

Composer packages live and die by composer.json. That’s where dependencies, autoload rules, and scripts get declared. It’s also where your static analyzer, your CI lint job, and your “what changed in this PR” reviewer focus 95% of their attention. package.json exists in plenty of Composer repos for unrelated reasons: bundled frontend assets, build tooling, contributor docs. Most reviewers see it and skip past. Plenty of auditing tools don’t even parse it when the parent project is registered with Packagist.

That’s the gap the attackers chose. Eight packages had perfectly clean Composer manifests. The malicious post-install hook lived in a file the ecosystem treats as someone else’s problem. The dropped binary executed on Linux hosts only, which is exactly the environment where the overwhelming majority of PHP production servers actually live. No Windows triggers, no Mac triggers, no obvious sandbox fingerprints. The whole campaign was designed to slip past whatever the maintainer was looking for and detonate only in the place where it would do real damage.

Packagist Composer repository logo on a dark background
Composer’s review surface focuses on composer.json. Attackers moved the payload one file over.

GitHub Is the Distribution Layer Now

The Laravel Lang hijack works on a different but related trust assumption. GitHub tags get treated as cryptographic anchors by half the ecosystem. They are not. A maintainer, or anyone who took over a maintainer account, can delete and re-create a tag against a different commit, and most installers will happily pull whatever HEAD that tag now points to. Composer’s behavior here is not unique. The same assumption shows up in Go modules, in older npm pull patterns, and in every CI job that does a shallow clone of a “trusted” tag without verifying the commit hash.

The Linux binary in the Packagist attack was hosted on a GitHub Releases URL. The Laravel Lang stealer was distributed through GitHub’s tag system. Attackers don’t need to spin up bulletproof hosting anymore. They use the same platform you whitelisted years ago because nobody wanted to argue with the engineering team about pulling dependencies from raw.githubusercontent.com. Your firewall lets it through. Your egress allowlist has github.com hard-coded at the domain level. Your endpoint protection trusts anything served from the GitHub namespace because everybody else does, and reputation lists agree.

This is what brute-force scanning misses. The traffic looks identical to ten thousand legitimate package installs running across your fleet today. The signature on the artifact is valid. The hosting reputation is pristine. Threat detection built around bad-domain feeds and known-malicious hashes was already weak against this attack class a year ago. Today, it’s effectively blind.

Staged Publishing Closes One Door, Not the Building

npm’s rollout of 2FA-gated staged publishing this week is the right move. The feature forces a human maintainer to pass a 2FA challenge before a published package version actually becomes installable. That kills a large category of credential-stuffing-driven supply chain attacks where an attacker grabs a stolen npm token, publishes a malicious version, and races to infect downstream users before the legitimate maintainer notices anything is wrong.

npm security illustration showing package access controls
Staged publishing forces a 2FA challenge before a published version becomes installable.

What staged publishing doesn’t fix is the broader pattern these Packagist and Laravel Lang attacks expose. Registry-side threat detection focuses on the obvious surfaces: declared dependencies, manifest fields the registry cares about, install scripts in the language the registry serves. Attackers have moved one layer over into wrong-file injection, tag mutability abuse, mutable releases, and CDN trust laundering. Registry operators can’t realistically scan every byte of every artifact at registry-wide volume looking for cross-ecosystem payloads. Which means the defender’s burden lands back where it always does. On the team consuming the dependency.

What To Do This Week

Strong incident response on dependency compromise starts before the compromise. Treat the build chain as a primary threat surface, not an afterthought to network perimeter controls. Defense in depth here is concrete and operational, and the work doesn’t require any specific vendor.

  • Pin every production dependency to a commit hash, never a tag or a floating version. If your packaging tool won’t let you do this, that’s the first bug to fix.
  • Lock down outbound network access from build runners and production hosts. github.com is not a single destination; carve out exactly which org and repo paths your build legitimately needs, and block the rest at the egress proxy.
  • Inventory every file your installer touches during a package install, including manifests for other ecosystems. If your PHP package ships a package.json, ask why before you trust the artifact in production.
  • Watch for post-install scripts that pull executables from GitHub Releases or any raw-content URL. That pattern is now hostile-by-default and should generate a high-priority alert in any sane detection stack.
  • Rehearse a dependency-compromise IR scenario. Which hosts ran the install? Which credentials did the build environment hold? How long has the malicious version been sitting in your lockfile across branches? You want practiced answers before you need them at 2 a.m.

Security hardening for the developer pipeline is not glamorous work. It is the only layer where defenders have real leverage in 2026. Registry operators can add 2FA gates and staged publishing all they want, and you should still assume the next compromise will look exactly like these two. Technically valid. Semantically poisoned. Hosted on infrastructure your firewall has never had a reason to question. Detection has to live at the file level, the egress level, and the IR-rehearsal level, because the registry’s own perimeter is no longer where the fight actually happens.

Sources

Take Control of Your Server Security

Don't let brute-force attacks slow you down. Try IPBan Pro risk-free for 30 days.

Secure. Automated. Lightweight.

Stay up to date with the latest news, releases and more.

Take Control of Your Server Security

Don't let brute-force attacks slow you down. Try IPBan Pro risk-free for 30 days.

Secure. Automated. Lightweight.