
Static and dynamic analysis tool that audits open-source packages for malicious, vulnerable, and risky attributes, with sandboxed installation to prevent supply-chain attacks.
Packj (pronounced package) is a tool to help to mitigate software supply chain attacks. It can detect malicious, vulnerable, abandoned, typo-squatting, and other "risky" packages from popular open-source package registries, such as NPM, RubyGems, and PyPI. It can be easily customized to minimize noise. Packj started as a PhD research project and is currently being developed under various govt grants.
Note Self-hosted Packj webserver and several integrations coming later this month 👊 Watch this repo to stay up to date.

We support multiple deployment models:
Use Packj to audit dependencies in pull requests.
- name: Packj Security Audit
uses: ossillate-inc/[email protected]
with:
# TODO: replace with your dependency files in the repo
DEPENDENCY_FILES: pypi:requirements.txt,npm:package.json,rubygems:Gemfile
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
View on GitHub marketplace. Example PR run.
The quickest way to try/test Packj is using Docker. Podman is also supported for containerized (isolated) runs.
docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help
Clone this repo,
git clone https://github.com/ossillate-inc/packj.git && cd packj
Install dependencies
bundle install && pip3 install -r requirements.txt
Start with help:
python3 main.py --help
Packj can vet pubished packages from NPM, PyPI, Rust, PHP, and Rubygems package registries. Rust and PHP support is WIP. We're actively adding support for registries. It also supports vetting local (unpublished) NPM and PyPI packages.
| Registry | Ecosystem | Supported |
|---|---|---|
| NPM | JavaScript | ✅ |
| PyPI | Python | ✅ |
| Cargo | Rust | ✅ |
| Rubygems | Ruby | ✅ |
| Packagist | PHP | ✅ |
| Docker | Docker | ❌ |
| Nuget | .NET | ✅ |
| Maven | Java | ✅ |
| Cocoapods | Swift | ❌ |
Packj offers the following tools:
Packj audits open-source software packages for "risky" attributes that make them vulnerable to supply chain attacks. For instance, packages with expired email domains (lacking 2FA), large release time gap, sensitive APIs or access permissions, etc. are flagged as risky.
Auditing the following is supported:
python3 main.py audit -p pypi:requests rubygems:overcommitpython3 main.py audit -f npm:package.json pypi:requirements.txtBy default, audit only performs static code analysis to detect risky code. You can paas -t or --trace flag to perform dynamic code analysis as well, which will install all requested packages under strace and monitor install-time behavior of packages. Please see the example output below.
$ docker run -v /tmp:/tmp/packj -it ossillate/packj:latest audit --trace -p npm:browserify
[+] Fetching 'browserify' from npm..........PASS [ver 17.0.0]
[+] Checking package description.........PASS [browser-side require() the node way]
[+] Checking release history.............PASS [484 version(s)]
[+] Checking version........................RISK [702 days old]
[+] Checking release time gap............PASS [68 days since last release]
[+] Checking author.........................PASS [[email protected]]
[+] Checking email/domain validity.......RISK [expired author email domain]
[+] Checking readme.........................PASS [26838 bytes]
[+] Checking homepage.......................PASS [https://github.com/browserify/browserify#readme]
[+] Checking downloads......................PASS [2M weekly]
[+] Checking repo URL.......................PASS [https://github.com/browserify/browserify]
[+] Checking repo data...................PASS [stars: 14189, forks: 1244]
[+] Checking if repo is a forked copy....PASS [original, not forked]
[+] Checking repo description............PASS [browser-side require() the node.js way]
[+] Checking repo activity...............PASS [commits: 2290, contributors: 207, tags: 413]
[+] Checking for CVEs.......................PASS [none found]
[+] Checking dependencies...................RISK [48 found]
[+] Downloading package from npm............PASS [163.83 KB]
[+] Analyzing code..........................RISK [needs 3 perm(s): decode,codegen,file]
[+] Checking files/funcs....................PASS [429 files (383 .js), 744 funcs, LoC: 9.7K]
[+] Installing package and tracing code.....PASS [found 5 process,1130 files,22 network syscalls]
=============================================
[+] 5 risk(s) found, package is undesirable!
=> Complete report: /tmp/packj_54rbjhgm/report_npm-browserify-17.0.0_hlr1rhcz.json
{
"undesirable": [
"old package: 702 days old",
"invalid or no author email: expired author email domain",
"generates new code at runtime",
"reads files and dirs",
"forks or exits OS processes",
]
}