Skip to content

dheidemann/npm-target-finder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The goal is to find packages that are sitting unnoticed deep down the dependency tree and are therefore potential targets for supply chain attacks.

npm-target-finder is essentially a combination of two simple scripts:

getter.js

Fetches npm packages with an upstream github url and parse metadata in packages.txt:

  • Package name
  • Maintainer count
  • Average daily pulls
  • Days since last github commit
  • Open PRs count
  • Open Issues count
  • Github star count

In the script you can define a threshold for minimal daily pulls. It is set to 1000 per default.

score-calculator.py

Reads package data from a file, calculates a score for each package based on defined thresholds for stars, daily average activity, recent commits, open pull requests, and open issues, and then outputs the top 20 packages sorted by their scores.

To configure the script, adjust the threshold values at the top.

Installation

Tip

Last time I ran this script it took approximately 5h to get the packages you can find in packages.txt. If you just want to play with the scores I suggest to use the python script below on the provided packages.txt.

getter.js

npm i
export GITHUB_TOKEN=gh_XXXXX # optional: provide a gh-token for higher rate limits
node getter.js

score-calculator.py

python3 score-calculator.py packages.txt

Latest results (11.05.25)

{'pkg': 'inherits', 'maintainer_count': 1, 'avg_daily': 1078414, 'days_since_commit': 571, 'open_prs': 2, 'open_issues': 4, 'stars': 353, 'repo_url': 'https://github.com/isaacs/inherits', 'score': 37.392133333333334}
{'pkg': 'isarray', 'maintainer_count': 1, 'avg_daily': 1026857, 'days_since_commit': 198, 'open_prs': 1, 'open_issues': 1, 'stars': 133, 'repo_url': 'https://github.com/juliangruber/isarray', 'score': 35.94356666666667}
{'pkg': 'isstream', 'maintainer_count': 1, 'avg_daily': 383899, 'days_since_commit': 3419, 'open_prs': 0, 'open_issues': 1, 'stars': 63, 'repo_url': 'https://github.com/rvagg/isstream', 'score': 31.26663333333333}
{'pkg': 'graceful-readlink', 'maintainer_count': 1, 'avg_daily': 392365, 'days_since_commit': 3055, 'open_prs': 0, 'open_issues': 0, 'stars': 9, 'repo_url': 'https://github.com/zhiyelee/graceful-readlink', 'score': 30.263833333333334}
{'pkg': 'util-deprecate', 'maintainer_count': 1, 'avg_daily': 482551, 'days_since_commit': 2372, 'open_prs': 0, 'open_issues': 1, 'stars': 38, 'repo_url': 'https://github.com/TooTallNate/util-deprecate', 'score': 29.570033333333335}
{'pkg': 'mkdirp', 'maintainer_count': 1, 'avg_daily': 781527, 'days_since_commit': 602, 'open_prs': 0, 'open_issues': 1, 'stars': 193, 'repo_url': 'https://github.com/isaacs/node-mkdirp', 'score': 29.135899999999996}
{'pkg': 'imurmurhash', 'maintainer_count': 1, 'avg_daily': 196020, 'days_since_commit': 4276, 'open_prs': 0, 'open_issues': 0, 'stars': 99, 'repo_url': 'https://github.com/jensyt/imurmurhash-js', 'score': 28.924}
{'pkg': 'is-property', 'maintainer_count': 1, 'avg_daily': 308028, 'days_since_commit': 3285, 'open_prs': 1, 'open_issues': 1, 'stars': 13, 'repo_url': 'https://github.com/mikolalysenko/is-property', 'score': 28.6176}
{'pkg': 'process-nextick-args', 'maintainer_count': 1, 'avg_daily': 481813, 'days_since_commit': 2151, 'open_prs': 0, 'open_issues': 2, 'stars': 32, 'repo_url': 'https://github.com/calvinmetcalf/process-nextick-args', 'score': 28.50543333333334}
{'pkg': 'pinkie-promise', 'maintainer_count': 1, 'avg_daily': 433151, 'days_since_commit': 2545, 'open_prs': 1, 'open_issues': 2, 'stars': 117, 'repo_url': 'https://github.com/floatdrop/pinkie-promise', 'score': 28.05336666666667}
{'pkg': 'is-posix-bracket', 'maintainer_count': 1, 'avg_daily': 285728, 'days_since_commit': 3322, 'open_prs': 0, 'open_issues': 0, 'stars': 13, 'repo_url': 'https://github.com/jonschlinkert/is-posix-bracket', 'score': 28.004266666666666}
{'pkg': 'buffer-shims', 'maintainer_count': 1, 'avg_daily': 302514, 'days_since_commit': 3118, 'open_prs': 0, 'open_issues': 2, 'stars': 12, 'repo_url': 'https://github.com/calvinmetcalf/buffer-shims', 'score': 27.5638}
{'pkg': 'xtend', 'maintainer_count': 1, 'avg_daily': 595456, 'days_since_commit': 1734, 'open_prs': 0, 'open_issues': 0, 'stars': 305, 'repo_url': 'https://github.com/Raynos/xtend', 'score': 27.468533333333333}
{'pkg': 'jodid25519', 'maintainer_count': 1, 'avg_daily': 260861, 'days_since_commit': 3390, 'open_prs': 0, 'open_issues': 1, 'stars': 34, 'repo_url': 'https://github.com/meganz/jodid25519', 'score': 27.310366666666663}
{'pkg': 'pinkie', 'maintainer_count': 1, 'avg_daily': 430655, 'days_since_commit': 2454, 'open_prs': 0, 'open_issues': 2, 'stars': 139, 'repo_url': 'https://github.com/floatdrop/pinkie', 'score': 27.245166666666666}
{'pkg': 'preserve', 'maintainer_count': 1, 'avg_daily': 288472, 'days_since_commit': 3149, 'open_prs': 0, 'open_issues': 0, 'stars': 14, 'repo_url': 'https://github.com/jonschlinkert/preserve', 'score': 27.22073333333333}
{'pkg': 'core-util-is', 'maintainer_count': 1, 'avg_daily': 583275, 'days_since_commit': 1348, 'open_prs': 0, 'open_issues': 3, 'stars': 103, 'repo_url': 'https://github.com/isaacs/core-util-is', 'score': 27.167499999999997}
{'pkg': 'once', 'maintainer_count': 1, 'avg_daily': 710970, 'days_since_commit': 578, 'open_prs': 0, 'open_issues': 2, 'stars': 222, 'repo_url': 'https://github.com/isaacs/once', 'score': 26.379000000000005}
{'pkg': 'mimeparse', 'maintainer_count': 1, 'avg_daily': 6467, 'days_since_commit': 4853, 'open_prs': 0, 'open_issues': 0, 'stars': 12, 'repo_url': 'https://github.com/kriskowal/mimeparse', 'score': 26.360566666666667}
{'pkg': 'strip-bom', 'maintainer_count': 1, 'avg_daily': 531743, 'days_since_commit': 1484, 'open_prs': 0, 'open_issues': 0, 'stars': 111, 'repo_url': 'https://github.com/sindresorhus/strip-bom', 'score': 26.03476666666667}

About

Find and evaluate potential targets for supply chain attacks in the npm registry

Resources

License

Stars

Watchers

Forks