Ultra-fast malware and vulnerability scanner for Node.js projects that checks your node_modules against the Aikido Security malware database with offline backup support. Uses a streaming, file-based scan for instant results—even with huge malware lists.
Requirements:
- Node.js (for JSON parsing and npm tree analysis)
- npm (for dependency installation and listing)
- Bash (script is POSIX-compliant, tested on macOS and Linux)
- Standard Unix tools:
sort,comm,grep,sed,tr,wc,awk(all included in coreutils) - Either
jqor Node.js (for parsing the malware JSON from the Aikido API; Node.js is preferred and required for full functionality)
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" "https://gitlab.com/api/v4/projects/opensourcetools%2Fnode-malware-scanner/repository/files/install-nodescan.sh/raw?ref=main" | bash# Scan current Node.js project
nodescan
# Scan all Node.js projects in subfolders
nodescan --recursive
# Recursive scan without npm install (faster)
nodescan --recursive --skip-install
# Force refresh cache (ignores cached dependency list)
nodescan --refresh
# Skip npm install step
nodescan --skip-install
# Show verbose output (includes absent packages)
VERBOSE=1 nodescan
# Use offline mode (skip API call)
nodescan --offline
# Show help
nodescan --help- Fetches latest malware data - Downloads from Aikido Security malware database API (107,000+ entries)
- Discovers projects - In recursive mode, finds all directories with
package.jsonfiles - Installs dependencies - Runs
npm installto ensure packages are up to date (can be skipped with--skip-install) - Scans each project - Uses
npm ls --jsonto get the complete dependency tree per project - Ultra-fast matching - Compares installed packages against the malware database using native streaming tools (
sort,comm) for instant set intersection - Reports results - Shows per-project malware findings and overall summary
- Caches results - Speeds up subsequent scans by caching based on
package-lock.jsonhash per project - Offline support - Falls back to local backup if API is unavailable
- ⚡ Ultra-fast scanning - Streaming, file-based set intersection for instant results, even with 100,000+ malware entries
- 🔄 Recursive scanning - Automatically finds and scans all Node.js projects in subfolders
- 🛡️ Live malware data - Uses Aikido Security's up-to-date malware database (107,000+ entries)
- 📱 Offline support - Works without internet using cached malware data
- 🧠 Smart caching - Caches dependency lists keyed by
package-lock.jsonhash per project - 📊 Comprehensive reporting - Shows per-project results and overall summary
- 🔄 Cache control -
--refreshflag to force cache rebuild - 🌐 API integration - Fetches latest malware data from Aikido Security
- 📦 Zero dependencies - Only requires Node.js and standard shell tools
The offline malware database (malware-packages.txt) is automatically kept up to date by a scheduled pipeline in GitLab CI:
- How it works:
- A scheduled CI job fetches the latest malware list from the Aikido Security API every hour.
- The job converts the JSON to the required
package@versionformat and commits it to the repository if there are changes. - This ensures the offline backup is always current, even if the API is temporarily unavailable.
- Benefits:
- Users always get the latest malware data, even in offline or air-gapped environments.
- No manual intervention is needed to update the offline database.
node-scanner.sh- Main malware scanner scriptmalware-packages.txt- Offline backup of malware database (auto-updated, 107,000+ entries)install-nodescan.sh- Installation script
VULN_INPUT_FILE- Path to malware packages list (default:~/.config/nodescan/malware-packages.txt)VULN_API_URL- Malware API endpoint (default: https://malware-list.aikido.dev/malware_predictions.json)VULN_CACHE_DIR- Cache directory (default:~/.cache/nodescan)VERBOSE=1- Enable verbose output and show absent packages
The installer:
- Downloads scanner to
~/.local/bin/nodescan - Downloads malware database to
~/.config/nodescan/malware-packages.txt - Adds
~/.local/binto your PATH - Creates a wrapper script that sets correct paths
rm ~/.local/bin/nodescan
rm ~/.local/bin/nodescan-core.sh
rm -rf ~/.config/nodescan
rm -rf ~/.cache/nodescanThen remove the PATH export from your shell config file (.zshrc, .bashrc, etc.).
$ nodescan
[LOG] Target list ready: 107447 entries (took 0s)
[LOG] Scanning 107447 targets against 1247 installed entries (using comm) (took 0s)
[LOG] Scan complete: 0 found, 107447 missed (took 0s)
===== PRESENT (0) =====
[LOG] All done. Total duration: 2s (targets=107447)$ nodescan --recursive --skip-install
🔍 Scanning: ./project1
===== PRESENT (0) =====
🔍 Scanning: ./project2
===== PRESENT (1) =====
[email protected]
📊 RECURSIVE SCAN SUMMARY
Projects scanned: 29
Total malware entries checked: 107447
😎 No malware detected in any project!Note: The ABSENT section is only shown when VERBOSE=1 is set to keep output focused on actual malware found.
This project is licensed under the MIT License. See the LICENSE file for details.
This software consumes malware data from Aikido Security via their public API for security research purposes. No Aikido data is redistributed or included in this software - it only fetches and processes the data at runtime. Users are responsible for compliance with Aikido's API terms of service.
Repository: https://gitlab.com/opensourcestools/node-malware-scanner Malware Database: https://malware-list.aikido.dev/malware_predictions.json (Aikido Security)