Malware in the Gist: How Malicious Packages Bypass Existing Security Tools
This talk demonstrates how threat actors leverage the NPM and PyPI package ecosystems to distribute malicious code that evades traditional security tools. It highlights how attackers target developers and CI/CD pipelines by exploiting the lack of security controls in package registries and the high volume of transitive dependencies in JavaScript projects. The presentation emphasizes that static analysis and standard EDR solutions often fail to detect this type of supply chain attack, which frequently uses obfuscation and legitimate-looking metadata to remain hidden. The speaker advocates for the use of package firewalls and manual vetting of dependencies to mitigate these risks.
Why Your CI/CD Pipeline Is Already Running Malicious Code
TLDR: Open-source package registries like NPM and PyPI are being flooded with malicious packages that bypass standard static analysis and EDR tools. Attackers are shifting from binary-based malware to interpreted source code that targets developers and CI/CD pipelines directly. To stop this, security teams must move beyond basic scanning and implement strict dependency vetting and package firewalls.
Security researchers have spent years obsessing over binary-based malware, building complex sandboxes and reverse-engineering workflows to catch malicious executables. While that work remains necessary, it has left a massive blind spot in the supply chain. The real action is happening in the package registries, where attackers are no longer bothering with compiled binaries. They are shipping plain, interpreted source code that executes during the install phase, and it is sailing right past your security stack.
The Failure of Traditional Detection
Most enterprise security tools are built to look for known bad signatures or suspicious binary behavior. When you pull a package from NPM or PyPI, your static analysis tools might check for OWASP A06:2021 – Vulnerable and Outdated Components, but they rarely inspect the install scripts themselves.
Attackers know this. They are using dependency confusion and typo-squatting to trick developers into pulling malicious versions of legitimate libraries. Because these packages are often just JavaScript or Python source code, they do not trigger the typical "malicious binary" alerts. Even worse, many of these packages are highly iterative. An attacker can push a new version of a package every few minutes, changing the C2 infrastructure or the payload structure, effectively rendering static signature-based detection useless.
Why Obfuscation Is Not a Smoking Gun
A common misconception among security teams is that obfuscated code equals malicious code. This is a dangerous assumption. Developers frequently obfuscate code to protect intellectual property or business logic. If your detection engine flags every obfuscated package as malicious, you will be buried in false positives within a week.
The real threat lies in the install and post-install hooks. In NPM, a package can define scripts in its package.json that run automatically when the package is installed.
"scripts": {
"preinstall": "node malicious-script.js",
"postinstall": "node exfil-data.js"
}
This is not a bug; it is a feature of the ecosystem. Attackers use these hooks to execute code before the developer even realizes the package is installed. By the time your security tools scan the project, the damage is done. The payload has already exfiltrated environment variables, API keys, or cloud credentials from the build environment.
Targeting the Developer's Environment
CI/CD pipelines are the ultimate target because they are where intellectual property meets high-privilege access. A build server usually has access to AWS keys, GitHub tokens, and internal secrets. When a malicious package executes in that environment, it does not need to escalate privileges. It inherits the permissions of the build process.
Pentesters should look at the build environment as a primary attack surface. During an engagement, do not just scan the application code. Audit the package-lock.json or requirements.txt files. Look for packages that have been recently updated or that have an unusually high number of transitive dependencies. The JavaScript ecosystem is particularly prone to this, with the average package pulling in hundreds of transitive dependencies, each one a potential vector for a supply chain attack.
Moving Toward Real Defense
If you are relying on standard EDR to catch this, you are already behind. EDR agents are often excluded from build directories to prevent performance degradation, and even when they are active, they struggle to distinguish between a legitimate build process and a malicious script.
The only way to effectively mitigate this is to stop trusting the public registry. Engineering teams need to implement a package firewall that acts as a gatekeeper between the developer and the registry. This firewall should:
- Block all packages by default.
- Only allow packages that have been manually vetted or pulled from a trusted, internal proxy.
- Monitor for unexpected network egress during the installation phase.
Tools like OSV provide excellent data on known malicious packages, but they are reactive. You need a proactive approach that assumes the registry is compromised. If you are a security researcher or a developer, stop treating dependencies as "just code." Treat them as untrusted third-party binaries that are executing with your credentials.
The next time you see a new, "hot" library being pushed to your team's Slack, take five minutes to audit its package.json before running npm install. It is the most effective security control you have.
Vulnerability Classes
Target Technologies
Attack Techniques
OWASP Categories
Up Next From This Conference
Similar Talks

Inside the FBI's Secret Encrypted Phone Company 'Anom'

Kill List: Hacking an Assassination Site on the Dark Web




