On May 1, 2022, npm removed a malicious package called gxm-reference-web-auth-server from the public registry. This targeted attack used encryption and multi-stage obfuscation to hide data exfiltration capabilities, aiming at a specific organization's private registry through dependency confusion.
Snyk Security Research identified this threat. Their analysis revealed techniques sophisticated enough to bypass standard static analysis tools, prompting a reevaluation of your current supply chain controls.
Timeline
Before May 1, 2022: The attacker published gxm-reference-web-auth-server to the public npm registry. The package name pattern suggests the target organization used a similar internal package name in their private registry.
Discovery window: Snyk's automated scanning detected suspicious behavior during package analysis. The malware's obfuscation required manual reverse engineering to fully understand.
May 1, 2022: npm removed the malicious package after notification.
Post-incident: Investigation revealed connections to CodeWhite, a red team operation, raising questions about whether this was an authorized security test or an actual attack mimicking red team techniques.
Which Controls Failed
The dependency confusion vector succeeded due to three control gaps:
No namespace protection. The target organization didn't reserve their internal package names in the public registry. When a developer ran npm install, the package manager pulled from public npm instead of the private registry because public packages resolve first by default.
Insufficient package verification. The installation pipeline didn't verify package signatures or checksums before execution. The malicious code ran during the install phase — before any application code loaded.
Missing runtime behavior monitoring. The package established outbound connections and exfiltrated data during installation. No monitoring flagged the anomalous network behavior from a supposedly benign authentication library.
The obfuscation and encryption techniques bypassed static analysis tools that many teams rely on as their primary supply chain defense. The malware encrypted its payload and only decrypted it at runtime.
What Standards Require
PCI DSS v4.0.1 Requirement 6.3.2 mandates secure development practices, including supply chain security. If your build pipeline can pull unauthenticated packages from public registries, you're not meeting this requirement.
NIST 800-53 Rev 5 Control SR-3 requires integrity verification tools to detect unauthorized software changes. A package that exfiltrates data during installation represents the supply chain compromise this control addresses.
ISO/IEC 27001:2022 Annex A.8.31 requires controls to reduce risks of unauthorized access or changes. If your CI/CD pipeline can install arbitrary packages without verification, you lack separation.
OWASP ASVS v4.0.3 Section 14.2.1 requires that all components come from trusted sources over secure links and are checked for tampering. The npm ecosystem makes this challenging, but the requirement stands.
Lessons and Action Items
Reserve Your Namespace
Register placeholder packages in public registries for any internal package names. Even if you never publish them, claim the namespace. This costs nothing and blocks the most obvious dependency confusion vector.
For npm, publish a minimal package with your internal naming pattern:
{
"name": "@yourorg-internal/package-name",
"version": "0.0.0",
"description": "Internal use only - not for public consumption"
}
Set your package manager to prefer your private registry for your organization's namespace. In .npmrc:
@yourorg-internal:registry=https://your-private-registry.com
Verify Before Execution
Implement checksum verification for all external dependencies. Generate lock files (package-lock.json, yarn.lock) in a trusted environment and verify them in CI/CD before installation.
Add a pre-install hook that validates package sources:
// verify-packages.js
const lockfile = require('./package-lock.json');
const allowedRegistries = ['https://your-private-registry.com'];
Object.entries(lockfile.packages).forEach(([name, pkg]) => {
if (pkg.resolved && !allowedRegistries.some(r => pkg.resolved.startsWith(r))) {
console.error(`Unauthorized registry for ${name}: ${pkg.resolved}`);
process.exit(1);
}
});
Monitor Installation Behavior
Your SIEM should ingest events from build environments. Flag any outbound connections during package installation that don't match expected patterns. The gxm-reference-web-auth-server package made HTTP requests during install — that's detectable if you're watching.
Create network policies that restrict build environments to only necessary registries and artifact repositories. Use egress filtering to block unexpected destinations.
Audit Dependencies Continuously
Run software composition analysis (SCA) tools in your pipeline, but don't rely solely on signature-based detection. The obfuscation techniques in this attack defeated simple pattern matching.
Implement behavioral analysis: sandbox new dependencies and monitor their installation and initialization behavior before allowing them into production pipelines. This catches runtime decryption and execution that static analysis misses.
Test Your Detection
Have your security team simulate a dependency confusion attack against your own infrastructure. Publish a benign test package to the public registry using an internal naming pattern and see if your controls catch it. If it gets pulled and installed, you have a gap.
The sophistication of this attack — encryption, multi-stage obfuscation, targeted naming — suggests we're past the point where basic package scanning provides adequate protection. Your supply chain security needs runtime verification, not just static checks.
If you're running builds that can install arbitrary public packages without verification, assume you've already been compromised. The question is whether you have the visibility to know it.



