| name | dependency-lockfile-audit |
| description | Detect typosquatting, malicious packages, and lockfile tampering in npm, pip, and composer dependencies. Covers lockfile integrity verification, known-malicious package detection, and supply chain attack prevention. Use when auditing dependencies, investigating suspicious packages, or hardening the supply chain. |
| version | 1.0 |
Dependency Lockfile Audit
Detect malicious, typosquatted, and vulnerable dependencies before they compromise your application. Supply chain attacks are increasingly common -- a single malicious package can exfiltrate all your environment variables on install.
The Rule
ALWAYS commit lockfiles. ALWAYS audit before installing. NEVER ignore security warnings.
Attack Vectors
| Attack | How it works | Example |
|---|
| Typosquatting | Package name looks like popular one | expresss instead of express |
| Dependency confusion | Private package name claimed on public registry | @company/utils published by attacker on npm |
| Malicious postinstall | Script runs on npm install | Steals .env, SSH keys, sends to attacker |
| Protestware | Maintainer adds destructive code in update | Wipes files, shows political messages |
| Abandoned takeover | Attacker gains control of unmaintained package | Injects crypto miner |
Audit Commands
npm (Node.js)
npm audit
npm audit --omit=dev
npm audit fix
npm query ':attr(scripts, [postinstall])' | jq '.[].name'
npm ci
pip (Python)
pip-audit
safety check --full-report
pip freeze > requirements.txt
composer (PHP/Laravel)
composer audit
composer validate --strict
Typosquatting Detection
Common Patterns to Watch For
# Character substitution
lodash → 1odash (L vs 1)
express → expresss (double letter)
react → reacct
# Scope confusion
@babel/core → @bable/core
@types/node → @typs/node
# Hyphen/underscore tricks
cross-env → crossenv
node-fetch → nodefetch
Automated Check Script
#!/bin/bash
echo "Checking for suspicious packages..."
DEPS=$(jq -r '.dependencies // {} | keys[]' package.json)
DEPS="$DEPS $(jq -r '.devDependencies // {} | keys[]' package.json)"
for pkg in $DEPS; do
INFO=$(curl -s "https://registry.npmjs.org/$pkg")
if echo "$INFO" | jq -e '.error' > /dev/null 2>&1; then
echo "WARNING: Package '$pkg' not found on registry!"
continue
fi
DOWNLOADS=$(curl -s "https://api.npmjs.org/downloads/point/last-week/$pkg" | jq '.downloads // 0')
if [ "$DOWNLOADS" -lt 100 ]; then
echo "WARNING: '$pkg' has only $DOWNLOADS weekly downloads (possible typosquat)"
fi
done
Lockfile Integrity
Why Lockfiles Matter
Without a lockfile, npm install can resolve to different versions on different machines. An attacker who publishes a malicious patch version will hit anyone without a lockfile.
Rules
- Always commit lockfiles (
package-lock.json, yarn.lock, pnpm-lock.yaml, composer.lock, Pipfile.lock)
- Use
npm ci in CI/CD (not npm install) -- fails if lockfile is out of sync
- Review lockfile diffs in PRs -- unexpected changes may indicate supply chain attack
- Pin exact versions for critical dependencies:
{
"dependencies": {
"stripe": "14.5.0",
"jsonwebtoken": "9.0.2"
}
}
Detect Lockfile Tampering
npm ci --ignore-scripts
npm rebuild
CI/CD Integration
GitHub Actions
name: Dependency Audit
on:
pull_request:
paths:
- 'package.json'
- 'package-lock.json'
- 'requirements.txt'
- 'Pipfile.lock'
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check lockfile exists
run: |
if [ ! -f package-lock.json ]; then
echo "ERROR: No lockfile found. Run 'npm install' and commit package-lock.json"
exit 1
fi
- name: Install with integrity check
run: npm ci --ignore-scripts
- name: Run security audit
run: npm audit --audit-level=high
- name: Check for install scripts
run: |
SCRIPTS=$(npm query ':attr(scripts, [postinstall])' 2>/dev/null | jq -r '.[].name' 2>/dev/null)
if [ -n "$SCRIPTS" ]; then
echo "Packages with postinstall scripts:"
echo "$SCRIPTS"
echo "Review these packages for malicious behavior"
fi
Safe Dependency Practices
- Minimize dependencies -- fewer deps = smaller attack surface
- Prefer well-known packages -- check download counts, maintainer reputation
- Lock versions in production -- use exact versions, not ranges
- Review before updating -- read changelogs, check for ownership changes
- Use
--ignore-scripts for initial install -- then audit scripts before running
- Set up Dependabot/Renovate -- automated PRs for security updates
- Never run
npm install from untrusted package.json -- check scripts first
Red Flags in a Package
- Published in the last 7 days with a name similar to a popular package
- Very few weekly downloads (< 100) for a "utility" package
postinstall script that runs obfuscated code
- Maintainer email is a disposable address
- Repository URL doesn't match package name
- Single version published (no history)
- Minified source code in the package (hiding malicious code)
PDPA 2024 Consequence
Finding #7 from forensic analysis: Suspicious/unverified dependencies.
If a malicious dependency exfiltrates user data from your application, you are liable under Seksyen 5(1) PDPA 2024 for failing to verify your supply chain. The court considers dependency management part of langkah keselamatan yang munasabah (reasonable security measures).