Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion docs/npm-scanner.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,33 @@ Scan installed packages or project dependencies for security issues.
./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.
Expand Down Expand Up @@ -150,7 +177,8 @@ Validation results are printed to stdout with:

## Environment Variables

- `TMPDIR` - Cache directory location (recommended: `/tmp`)
- `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

Expand Down
97 changes: 97 additions & 0 deletions npm-scanner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Commands:
scan Scan installed packages or project dependencies for security issues
validate Validate a package before installation
list-iocs Display all current indicators of compromise (IOCs)
cache Manage the npm metadata cache
help Show this help message
version Show version information

Expand All @@ -33,6 +34,8 @@ Examples:
npm-scanner.sh scan --local ~/projects # Scan node_modules directories
npm-scanner.sh validate lodash # Check package before installing
npm-scanner.sh list-iocs # Show all IOCs being checked
npm-scanner.sh cache --status # Show cache statistics
npm-scanner.sh cache --clear # Clear all cached data

Run 'npm-scanner.sh <command> --help' for command-specific options.

Expand Down Expand Up @@ -114,6 +117,97 @@ cmd_list_iocs() {
echo ""
}

show_cache_help() {
cat << 'EOF'
Usage: npm-scanner.sh cache [options]

Manage the npm metadata cache.

Options:
--status Show cache statistics (default if no option given)
--clear Clear all cached data
--clear-expired Clear only expired cache entries

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)

Examples:
npm-scanner.sh cache # Show cache status
npm-scanner.sh cache --status # Show cache status
npm-scanner.sh cache --clear # Clear all cache
npm-scanner.sh cache --clear-expired # Clear only expired entries
EOF
}

cmd_cache() {
source "$SCRIPTS_DIR/npm-audit-lib.sh"

local action="status"

while [ $# -gt 0 ]; do
case "$1" in
--help|-h)
show_cache_help
exit 0
;;
--status)
action="status"
shift
;;
--clear)
action="clear"
shift
;;
--clear-expired)
action="clear-expired"
shift
;;
*)
echo "Unknown option: $1"
show_cache_help
exit 1
;;
esac
done

case "$action" in
status)
local stats=$(lib_get_cache_stats_detailed)
local count=$(echo "$stats" | cut -d'|' -f1)
local size_mb=$(echo "$stats" | cut -d'|' -f2)
local location=$(echo "$stats" | cut -d'|' -f3)
local max_size=$(echo "$stats" | cut -d'|' -f4)
local max_age=$(echo "$stats" | cut -d'|' -f5)
local pkglist_count=$(lib_get_pkglist_cache_stats)

echo ""
echo "npm-scanner Cache Status"
echo "========================"
echo "Location: ~/.npm-scanner/"
echo ""
echo "Package metadata (npm registry data):"
echo " Packages: $count cached"
echo " Size: ${size_mb} MB / ${max_size} MB limit"
echo " Expiration: ${max_age} days"
echo ""
echo "Package lists (node_modules indexes):"
echo " Directories: $pkglist_count cached"
echo " Invalidation: on directory change"
echo ""
;;
clear)
local removed=$(lib_clear_cache)
local pkglist_removed=$(lib_clear_pkglist_cache)
echo "Cleared $removed cached packages, $pkglist_removed directory indexes"
;;
clear-expired)
local removed=$(lib_clear_expired_cache)
echo "Cleared $removed expired cache entries"
;;
esac
}

# Parse command
if [ $# -eq 0 ]; then
show_help
Expand All @@ -133,6 +227,9 @@ case "$COMMAND" in
list-iocs)
cmd_list_iocs
;;
cache)
cmd_cache "$@"
;;
help|--help|-h)
show_help
;;
Expand Down
45 changes: 36 additions & 9 deletions scripts/audit-installed-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -380,24 +380,43 @@ is_valid_npm_package() {
return 1
}

# Count valid npm packages in a directory
# Count valid npm packages in a directory (with caching)
# Usage: count_valid_packages <node_modules_dir> <max_depth> [show_progress]
count_valid_packages() {
local nm_dir=$1
local max_depth=$2
local show_progress=${3:-false}
local count=0

while IFS= read -r pkg_json_path; do
[ -z "$pkg_json_path" ] && continue
local pkg_dir=$(dirname "$pkg_json_path")
if is_valid_npm_package "$pkg_dir"; then
count=$((count + 1))
if [ "$show_progress" = true ]; then
printf "\rCounting packages... %d" "$count" >&2
# Try to get cached package list
local cached_list=$(lib_get_cached_pkglist "$nm_dir" "$max_depth")

if [ -n "$cached_list" ]; then
# Use cached list - just count lines
count=$(echo "$cached_list" | wc -l | tr -d ' ')
if [ "$show_progress" = true ]; then
printf "\rCounting packages... %d (cached)" "$count" >&2
fi
else
# Build package list and cache it
local pkg_list=""
while IFS= read -r pkg_json_path; do
[ -z "$pkg_json_path" ] && continue
local pkg_dir=$(dirname "$pkg_json_path")
if is_valid_npm_package "$pkg_dir"; then
count=$((count + 1))
pkg_list="${pkg_list}${pkg_json_path}"$'\n'
if [ "$show_progress" = true ]; then
printf "\rCounting packages... %d" "$count" >&2
fi
fi
done < <(find "$nm_dir" -maxdepth "$max_depth" -name "package.json" -type f 2>/dev/null)

# Save to cache (remove trailing newline)
if [ -n "$pkg_list" ]; then
echo -n "${pkg_list%$'\n'}" | lib_save_pkglist_cache "$nm_dir" "$max_depth"
fi
done < <(find "$nm_dir" -maxdepth "$max_depth" -name "package.json" -type f 2>/dev/null)
fi

echo "$count"
}
Expand Down Expand Up @@ -506,6 +525,14 @@ show_detection_summary() {
echo " - Attacker patterns: ${#ATTACKER_PATTERNS[@]}"
echo " - Typosquatting targets: ${#TYPOSQUATTING_TARGETS[@]}"
echo " - Issues found: $issues_found"

# Show cache status
local cache_stats=$(lib_get_cache_stats_detailed)
local cache_count=$(echo "$cache_stats" | cut -d'|' -f1)
local cache_size=$(echo "$cache_stats" | cut -d'|' -f2)
local cache_location=$(echo "$cache_stats" | cut -d'|' -f3)
echo ""
echo "Cache: $cache_count packages (${cache_size} MB) in $cache_location"
}

# Show what the scan checks for
Expand Down
5 changes: 3 additions & 2 deletions scripts/generate-summary-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ echo ""
echo "================================================"
echo "CACHE STATISTICS"
echo "================================================"
echo "Packages cached: $(ls /tmp/.npm-audit-cache/ 2>/dev/null | wc -l)"
echo "Cache location: /tmp/.npm-audit-cache/"
CACHE_DIR="${HOME}/.npm-scanner/cache"
echo "Packages cached: $(ls "$CACHE_DIR" 2>/dev/null | wc -l | tr -d ' ')"
echo "Cache location: $CACHE_DIR"
echo ""

echo "================================================"
Expand Down
Loading