GithubHelp home page GithubHelp logo

ossillate-inc / packj Goto Github PK

View Code? Open in Web Editor NEW
615.0 10.0 37.0 1.34 MB

Packj stops :zap: Solarwinds-, ESLint-, and PyTorch-like attacks by flagging malicious/vulnerable open-source dependencies ("weak links") in your software supply-chain

Home Page: https://packj.dev

License: GNU Affero General Public License v3.0

Python 77.75% Ruby 2.62% Dockerfile 0.42% Shell 0.59% Makefile 0.06% Java 18.57%
malware npm pypi python security security-audit security-tools vulnerability rubygems supply-chain-security

packj's Introduction

Β  Packj flags malicious/risky open-source packages

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.

GitHub Stars Prs Welcome Github Commit Activity Discord License: AGPL v3 Docker

Note Self-hosted Packj webserver and several integrations coming later this month πŸ‘Š Watch this repo to stay up to date.

demo video

Contents

  • Get started - available as Docker image, GitHub Action, and packages
  • Functionality - deep static/dynamic code analysis and sandboxing
  • Supported ecosystems - NPM, PyPI, Rubygems, PHP, Rust
  • Our story - started as a PhD research project and is backed by govt grants
  • Why Packj - existing CVE scanners ASSUME code is BENIGN and not analyze its behavior
  • Customization - turn off alerts as per your threat model to reduce noise
  • Malware found - reported over 70 malicious PyPI and RubyGems packages
  • Talks and videos - presentations from PyCon, OpenSourceSummit, BlackHAT
  • Project roadmap - view or suggest new features; join our discord channel
  • Team and collaboration - lead by Cybersecurity researchers from academia/industry
  • FAQ - supported package managers, commonly asked questions on techniques, and more

Get started

We support multiple deployment models:

1. GitHub runner

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.

2. Docker image (recommended)

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

3. Source repo

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 

Supported ecosystems

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 ❌

Functionality

Packj offers the following tools:

  • Audit - to vet a package for "risky" attributes.
  • Sandbox - for safe installation of a package.

Auditing a package

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:

  • multiple packages: python3 main.py audit -p pypi:requests rubygems:overcommit
  • dependency files: python3 main.py audit -f npm:package.json pypi:requirements.txt

By 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.

Show example run/output

$ 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",
    ]
}

WARNING: since packages could execute malicious code during installation, it is recommended to ONLY use -t or --trace when running inside a Docker container or a Virtual Machine.

Audit can also be performed in Docker/Podman containers. Please find details on risky attributes and how to use at Audit README.

Sandboxed package installation

Packj offers a lightweight sandboxing for safe installation of a package. Specifically, it prevents malicious packages from exfiltrating sensitive data, accessing sensitive files (e.g., SSH keys), and persisting malware.

It sandboxes install-time scripts, including any native compliation. It uses strace (i.e., NO VM/Container required).

Please find details on the sandboxing mechanism and how to use at Sandbox README.

Show example run/output

$ python3 main.py sandbox gem install overcommit

Fetching: overcommit-0.59.1.gem (100%)
Install hooks by running `overcommit --install` in your Git repository
Successfully installed overcommit-0.59.1
Parsing documentation for overcommit-0.59.1
Installing ri documentation for overcommit-0.59.1

#############################
# Review summarized activity
#############################

[+] Network connections
    [+] DNS (1 IPv4 addresses) at port 53 [rule: ALLOW]
    [+] rubygems.org (4 IPv6 addresses) at port 443 [rule: IPv6 rules not supported]
    [+] rubygems.org (4 IPv4 addresses) at port 443 [rule: ALLOW]
[+] Filesystem changes
/
└── home
    └── ubuntu
        └── .ruby
            β”œβ”€β”€ gems
            β”‚   β”œβ”€β”€ iniparse-1.5.0 [new: DIR, 15 files, 46.6K bytes]
            β”‚   β”œβ”€β”€ rexml-3.2.5 [new: DIR, 77 files, 455.6K bytes]
            β”‚   β”œβ”€β”€ overcommit-0.59.1 [new: DIR, 252 files, 432.7K bytes]
            β”‚   └── childprocess-4.1.0 [new: DIR, 57 files, 141.2K bytes]
            β”œβ”€β”€ cache
            β”‚   β”œβ”€β”€ iniparse-1.5.0.gem [new: FILE, 16.4K bytes]
            β”‚   β”œβ”€β”€ rexml-3.2.5.gem [new: FILE, 93.2K bytes]
            β”‚   β”œβ”€β”€ childprocess-4.1.0.gem [new: FILE, 34.3K bytes]
            β”‚   └── overcommit-0.59.1.gem [new: FILE, 84K bytes]
            β”œβ”€β”€ specifications
            β”‚   β”œβ”€β”€ rexml-3.2.5.gemspec [new: FILE, 2.7K bytes]
            β”‚   β”œβ”€β”€ overcommit-0.59.1.gemspec [new: FILE, 1.7K bytes]
            β”‚   β”œβ”€β”€ childprocess-4.1.0.gemspec [new: FILE, 1.8K bytes]
            β”‚   └── iniparse-1.5.0.gemspec [new: FILE, 1.3K bytes]
            β”œβ”€β”€ bin
            β”‚   └── overcommit [new: FILE, 622 bytes]
            └── doc
                β”œβ”€β”€ iniparse-1.5.0
                β”‚   └── ri [new: DIR, 119 files, 131.7K bytes]
                β”œβ”€β”€ rexml-3.2.5
                β”‚   └── ri [new: DIR, 836 files, 841K bytes]
                β”œβ”€β”€ overcommit-0.59.1
                β”‚   └── ri [new: DIR, 1046 files, 1.5M bytes]
                └── childprocess-4.1.0
                    └── ri [new: DIR, 272 files, 297.8K bytes]

[C]ommit all changes, [Q|q]uit & discard changes, [L|l]ist details:

Our story

TL;DR Packj started as a PhD research project. It is backed by various government grants.

Show long answer

Packj started as an academic research project. Specifically, the static code analysis techniques used by Packj are based on cutting-edge Cybersecurity research: MalOSS project by our research group at Georgia Tech.

academic paper

Packj is backed by generous grants from NSF, GRA, and ALInnovate.

Why Packj

TL;DR The state-of-the-art vulnerability scanners assume that the third-party open-source code is BENIGN. Therefore, all such tools ONLY address threats from accidental programming bugs in benign code (a.k.a. CVEs such as Log4J). They DO NOT protect against Solarwinds-like modern software supply-chain attacks from deliberately bad (a.k.a. malicious) code that is propagated by bad actors using new vulnerabilities in the supply channel, including dependency confusion, typo-squatting, protestware (sabotaging), account hijacking, and social engineering. A recent (Dec'22) example is PyTorch package that was compromised using dependency confusion vulnerability (no CVE assigned).

Packj not only audits for CVEs, but also performs deep static+dynamic code analysis as well as metadata checks to detect any "risky" behavior and attributes, such as spawning of shell, use of SSH keys, mismatch of GitHub code vs packaged code (provenance), lack of 2FA, and several more. Such insecure attributes do not qualify as as CVEs, which is why none of the existing tools can flag them. Packj can flag malicious, typo-squatting, abandoned, vulnerable, and other insecure dependencies (weak links) in your software supply chain.

Show long answer

The current software supply chain threat model assumes that the third-party open-source code is benign, and therefore, security vulnerabilities are only tracked for accidental programming bugs (a.k.a. CVEs). As such, all existing open-source vulnerability scanners ONLY report publicly known CVEs and address threats from accidental bugs in benign code.

A typical example of an accidental programming bug is a missing bounds check on user input, which makes the code vulnerable to buffer overflow attacks. Real-world popular examples include Log4J and HeartBleed. Attackers need to develop an exploit to trigger CVEs (e.g., a crafted TCP/IP packet in case of HeartBleed or a numerically high input to cause buffer overflow). CVEs can be fixed by patching or upgrading to a newer version of the library (e.g., newer version of Log4J fixes the CVE).

The modern software supply chain threat landscape shifted after the Solarwinds attack. Bad actors have found new vulnerabilities, but this time in the supply channel, not code. These new vulnerabilities such as dependency confusion, typo-squatting, protestware (sabotaging), account hijacking, and social engineering are being exploited to propagate malware. Thousands of compromised NPM/PyPI/Ruby packages have been reported.

In contrast to CVEs, malware is deliberately bad (a.k.a. malicious) code. Moreover, malware itself is an exploit and cannot be patched or fixed by upgrading to a newer version. For example, dependency confusion attack was intentionally malicious; it did not exploit any accidental programming bug in the code. Similarly, an author of popular package sabotaging their own code to protest against the war is very much intentional and does not exploit any CVEs. Typo-squatting is another attack vector that bad actors use to propagate malware in popular open-source package registries: it exploits typos and inexperience of devs, not accidental programming bugs or CVEs in the code.

Existing scanners FAIL to detect these Solarwinds-like modern software supply-chain attacks from deliberately vulnerable (malicious) code. These tools simply scan the source code for open-source dependencies, compile a list of all dependencies being used, and look each <dependency-NAME, dependency-VERSION> up in a database (e.g., NVD) to report affected package versions (e.g., vulnerable version of Log4J, LibSSL version affected by HeartBleed).

Packj not only audits for CVEs, but also performs deep static+dynamic code analysis as well as metadata checks to detect any "risky" behavior and attributes, such as spawning of shell, use of SSH keys, mismatch of GitHub code vs packaged code (provenance), lack of 2FA, and several more. Such insecure attributes do not qualify as as CVEs, which is why none of the existing tools can flag them. Packj can flag malicious, typo-squatting, abandoned, vulnerable, and other insecure dependencies (weak links) in your software supply chain. Please read more at Audit README

Customization

Packj can be easily customized (zero noise) to your threat model. Simply add a .packj.yaml file in the top dir of your repo/project and reduce alert fatigue by commenting out unwanted attributes.

Malware found

We found over 40 and 20 malicious packages on PyPI and Rubygems, respectively using this tool. A number of them been taken down. Refer to an example below:

Show example malware

$ python3 main.py audit pypi:krisqian

[+] Fetching 'krisqian' from pypi...OK [ver 0.0.7]
[+] Checking version...OK [256 days old]
[+] Checking release history...OK [7 version(s)]
[+] Checking release time gap...OK [1 days since last release]
[+] Checking author...OK [[email protected]]
    [+] Checking email/domain validity...OK [[email protected]]
[+] Checking readme...ALERT [no readme]
[+] Checking homepage...OK [https://www.bilibili.com/bangumi/media/md140632]
[+] Checking downloads...OK [13 weekly]
[+] Checking repo_url URL...OK [None]
[+] Checking for CVEs...OK [none found]
[+] Checking dependencies...OK [none found]
[+] Downloading package 'KrisQian' (ver 0.0.7) from pypi...OK [1.94 KB]
[+] Analyzing code...ALERT [needs 3 perms: process,network,file]
[+] Checking files/funcs...OK [9 files (2 .py), 6 funcs, LoC: 184]
=============================================
[+] 6 risk(s) found, package is undesirable!
{
    "undesirable": [
        "no readme",
        "only 45 weekly downloads",
        "no source repo found",
        "generates new code at runtime",
        "fetches data over the network: ['KrisQian-0.0.7/setup.py:40', 'KrisQian-0.0.7/setup.py:50']",
        "reads files and dirs: ['KrisQian-0.0.7/setup.py:59', 'KrisQian-0.0.7/setup.py:70']"
    ]
}
=> Complete report: pypi-KrisQian-0.0.7.json
=> View pre-vetted package report at https://packj.dev/package/PyPi/KrisQian/0.0.7

Packj flagged KrisQian (v0.0.7) as suspicious due to absence of source repo and use of sensitive APIs (network, code generation) during package installation time (in setup.py). We decided to take a deeper look, and found the package malicious. Please find our detailed analysis at https://packj.dev/malware/krisqian.

More examples of malware we found are listed at https://packj.dev/malware Please reach out to us at [email protected] for full list.

Resources

To learn more about Packj tool or open-source software supply chain attacks, refer to our

PyConUS'22 Video OSSEU'22 Video

Feature roadmap

  • Add Rust analyzer. Rust is a work in progress [ETA: Feb '24].
  • Add functionality to detect several (TODO) "risky" code as well as metadata attributes [ETA: Feb '24].
  • Self-hosted Packj webserver and several useful integrations (e.g., Gitlab runner) [ETA: Apr'24].

Watch πŸ‘€ this repo to stay up to date.

Have a feature or support request? Please visit our GitHub discussion page or join our discord community for discussion and requests.

Team and contributors

Packj has been developed by Cybersecurity researchers at Ossillate Inc. and external collaborators to help developers mitigate risks of supply chain attacks when sourcing untrusted third-party open-source software dependencies. We thank our developers and collaborators. Show your appreciation by giving us a ⭐ if you like our work.

We welcome code contributions with open arms. See CONTRIBUTING.md guidelines. Found a bug? Please open an issue. Refer to our SECURITY.md guidelines to report a security issue.

FAQ

What Package Managers (Registries) are supported?

Packj can currently vet NPM, PyPI, and RubyGems packages for "risky" attributes. We are adding support for Rust.

What techniques does Packj employ to detect risky/malicious packages?

Packj uses static code analysis, dynamic tracing, and metadata analysis for comprehensive auditing. Static analysis alone is not sufficient to flag sophisticated malware that can hide itself better using code obfuscation. Dynamic analysis is performed by installing the package under strace and monitoring it's runtime behavior. Please read more at Audit README.

Does it work on obfuscated calls? For example, a base 64 encrypted string that gets decrypted and then passed to a shell?

This is a very common malicious behavior. Packj detects code obfuscation as well as spawning of shell commands (exec system call). For example, Packj can flag use of getattr() and eval() API as they indicate "runtime code generation"; a developer can go and take a deeper look then. See main.py for details.

packj's People

Contributors

aegilops avatar ashishbijlani avatar badochov avatar codaishin avatar dependabot[bot] avatar kyerussell avatar packjguard avatar shivaabhishek07 avatar tatianahub avatar the-elves avatar werifu avatar wurstbrot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

packj's Issues

Source code?

Hi:
I would love to test this tool (I happen to have a few commits in strace) but I cannot trust this non-open source binary plug at
https://github.com/ossillate-inc/packj/blame/4797939a09e5fb113d60577515044e905afd4fa0/packj/sandbox/README.md#L142

You wrote:

We are not ready to immediately open source this small piece yet. This is NOT to implement security by obscurity, but to avoid easy copy-and-reuse scenarios. The rest of the tool is completely open; this piece will be too, eventually.

When will you make this open source?

Provide `sandbox.o` for other architectures

Is your feature request related to a problem? Please describe.
I cannot use sandbox.o in non-x86-64 environments, e.g. More concretely/specifically, I can't run Packj on an Apple Silicon (ARM) Mac without using some sort of emulation/translation/virtualisation layer (e.g. running the amd64 Docker image).

Describe the solution you'd like
Ideally, sandbox.o should be open-sourced, but I can see that this has been discussed elsewhere (e.g. #67). In which case, a compilation should be provided for other common architectures (like ARM).

Specify path to .packj.yaml

packj should have the option to specify the path to .packj.yaml.

For instance:

packj --template ../.packj.yaml

or

python3 main.py --template ../.packj.yaml

Linux pip3 package installation error

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Boot up Kali VM or any other distro (tested on Ubuntu too)
  2. Run pip3 install packj
  3. See error

Expected behavior
Packj gets installed

Screenshots or logs

          [+] Clonning strace...Done
          [+] Unpacking strace (est: 2mins)...Failed [log: /tmp/strace.build.log]
      ld -shared -L. -lstrace -ldl -o libsbox.so sandbox.o
      Traceback (most recent call last):
        File "/tmp/pip-install-nrse4_2a/packj_2803a9ff09a146a3a815e8741bc39614/setup.py", line 61, in run
          setup_sandbox(target_dir)
        File "/tmp/pip-install-nrse4_2a/packj_2803a9ff09a146a3a815e8741bc39614/setup.py", line 38, in setup_sandbox
          raise Exception(f'Failed to install sandbox:\n{stderr}')
      Exception: Failed to install sandbox:
      (None, b'ld: cannot find -lstrace: No such file or directory\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: Relocations in generic ELF (EM: 62)\nld: sandbox.o: error adding symbols: file in wrong format\nmake: *** [Makefile:14: all] Error 1\n')
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/tmp/pip-install-nrse4_2a/packj_2803a9ff09a146a3a815e8741bc39614/setup.py", line 65, in <module>
          setup(
        File "/usr/lib/python3/dist-packages/setuptools/__init__.py", line 87, in setup
          return distutils.core.setup(**attrs)
        File "/usr/lib/python3/dist-packages/setuptools/_distutils/core.py", line 185, in setup
          return run_commands(dist)
        File "/usr/lib/python3/dist-packages/setuptools/_distutils/core.py", line 201, in run_commands
          dist.run_commands()
        File "/usr/lib/python3/dist-packages/setuptools/_distutils/dist.py", line 968, in run_commands
          self.run_command(cmd)
        File "/usr/lib/python3/dist-packages/setuptools/dist.py", line 1217, in run_command
          super().run_command(command)
        File "/usr/lib/python3/dist-packages/setuptools/_distutils/dist.py", line 987, in run_command
          cmd_obj.run()
        File "/tmp/pip-install-nrse4_2a/packj_2803a9ff09a146a3a815e8741bc39614/setup.py", line 63, in run
          distutils_logger.warning(f'Custom build failed: {str(e)}! Sandbox feature will not work')
      AttributeError: module 'distutils.log' has no attribute 'warning'
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

Γ— Encountered error while trying to install package.
╰─> packj

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

Desktop (please complete the following information):

  • OS: Kali Linux (Debian) and Ubuntu, both VM

Additional context
Seems to fully not install, running packj afterwards throws that the package is not installed

Command 'packj' not found, did you mean:
  command 'pack' from deb liballegro4-dev
  command 'packf' from deb mmh
  command 'packf' from deb nmh
  command 'pack2' from deb pack2
Try: sudo apt install <deb name>

User/Custom PyPI repository scanning capability

Is your feature request related to a problem? Please describe.
It would be great if users could not only scan public repos, but packj would allow to scan packages places in user defined repositories, such as JFrog etc.

Describe the solution you'd like
Allow package scanning from user/custom defined repositories such as JFrog. Current functionality only allows packages scan that are located in public repos.

Describe alternatives you've considered
None. One of the options is package download and source code investigation or scans with other locally sources tools.

Additional context
Atm N/A.

podman not detected as docker

$ podman run -v /tmp:/tmp/packj ossillate/packj:latest audit --trace pypi apsw *** You've requested package installation trace *** We recommend running in Docker. Continue (N/y): EOF when reading a line

If I include -i in the command line (connect stdin) then I can answer Y and all works as expected.

Support for maven/Java

Many enterprises use java and maven. I think adding support for that would make this tool more popular.

[+] Fetching 'browserify' from npm..........FAIL [package not found!]

When I run:
python3 main.py audit -p npm:browserify --debug

Get Following output:
*** NOTE: Running in debug mode (log: /tmp/packj_audit_bwbde3qu/debug_kzpj3kik.log) ***

===============================================
Auditing npm package browserify (ver: latest)

[+] Fetching 'browserify' from npm..........FAIL [package not found!]

=> HTML summary available at: /tmp/packj_audit_bwbde3qu/report_stsfndao.html

/tmp/packj_audit_bwbde3qu/debug_kzpj3kik.log:
09:47:25,568 root DEBUG fail in get_metadata for pkg browserify: Failed to parse: https://registry.npmjs.org/browserify

/tmp/packj_audit_bwbde3qu/report_stsfndao.html:

<title> Packj security audit report </title>

Packj audit found 0/0 risky dependencies.

Click here for details

	</table>
</details>
Registry Package Version Risks

Failed to dump json content to file: Object of type Commit is not JSON serializable

Describe the bug
When auditing a package I always get the message:
Failed to dump json content to file /tmp/report_file_name.json: Object of type Commit is not JSON serializable.

To Reproduce
Steps to reproduce the behavior:

  1. Execute the command:
    docker run -v /tmp:/tmp/packj -it ossillate/packj:latest audit --trace -p npm:browserify
  2. Look at the end of the report
  3. See error:
    Failed to dump json content to file /tmp/packj/packj_audit_xw3c332_/report_4fa1somg.json: Object of type Commit is not JSON serializable

Expected behavior
There should be a report in JSON format listing the reasons why the package is undesirable.
Like this:
=> 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",
]
}

Screenshots
Error message:
error_message

Additional context

  1. I found that the JSON report files are incorrect. For example:
    incorrect_json_file

  2. The same error appears when I run the program without using docker.

Fails on some google shit

virtualenv packj
. packj/bin/activate
pip install -r requirements.txt

(packj) uzer@smarttop ~/packj $
python3 /home/uzer/packj.git/main.py pypi yt-dlp
Traceback (most recent call last):
  File "/home/uzer/packj.git/main.py", line 23, in <module>
    from static_util import get_static_proxy_for_language
  File "/home/uzer/packj.git/static_util.py", line 4, in <module>
    from static_proxy.py_analyzer import PyAnalyzer
  File "/home/uzer/packj.git/static_proxy/py_analyzer.py", line 13, in <module>
    import proto.python.ast_pb2 as ast_pb2
  File "/home/uzer/packj.git/proto/python/ast_pb2.py", line 32, in <module>
    _descriptor.EnumValueDescriptor(
  File "/home/uzer/packj/lib/python3.8/site-packages/google/protobuf/descriptor.py", line 755, in __new__
    _message.Message._CheckCalledFromGeneratedFile()
TypeError: Descriptors cannot not be created directly.
If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.
If you cannot immediately regenerate your protos, some other possible workarounds are:
 1. Downgrade the protobuf package to 3.20.x or lower.
 2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and will be much slower).

More information: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates

Fine grained control at package level

Describe the solution you'd like
I would like the ability to control/tune the audit alerts at a package level.

Additional context
By placing a packj.yaml file at project level, I would like the ability to have a global set of audit alert config and then be able to override this for a particular package. This means we still get full audit alerting but can silence or tune the values for a package we have reviewed and trust. I guess this would need to be for a version or hash incase and updated version becomes malicious.

Analysis of the Tracing Log

First, thanks for the amazing work!

I want to check my understanding of the current implementation of tracing. If we specify -t, the installation will be traced with strace -f -ttt -T -o strace.log <cmd>. Then the tracing log will be parsed by parse_trace_file. If the parsing succeed, an OK message would appear with a brief summary of syscalls.

To me, it seems that the tracing log is only "parsed", but not "analyzed". So if some suspicious activities are logged into the tracing log, it will still report an OK message. Then, a manual analysis of the tracing log is required to draw a conclusion of whether it is malicious or not. Is it correct?

BTW, the current version does not support tracing for local packages. I find it only requires a few lines of changes to support tracing local_nodejs:/path/to/pkg. Is there anyone working on this? I can propose a PR if needed.

Add version option

Is your feature request related to a problem? Please describe.
No, this is a new feature.

Describe the solution you'd like
When running packj -v or packj --version it will display the version number of the tool.

Describe alternatives you've considered
Passing a random string as the command to the tool returns and error. The prefix of the error is the app version string. I am considering parsing this but a dedicated command -v --version would be more standard.

Packj does not identify Python packages with 'extras'

Describe the bug
Python packages have the concept of 'extras'. As described by the Python packaging tutorial:

Extras are optional β€œvariants” of a package, which may include additional dependencies, and thereby enable additional functionality from the package.

Packj does not parse out these 'extras' when reading in a requirements.txt file.

I am new to Packj so unsure if Packj goes as far as to resolve a package's dependencies. I assume that it doesn't?

If I'm right, one could definitely argue that Packj should instead be run against a 'flattened' set of Python requirements (where all transient dependencies are included at the top level), e.g. the requirements.txt resulting from 'compiling' a requirements.in in the pip-tools workflow. And if Packj does consider dependencies, it's obviously still best practice to run it against a resolved set of dependencies anyway. In this case though it might be worth explicitly noting (in the error output) that the given package can't be resolved by virtue of it containing an extra, instead of trying (and inherently always failing) to find it in PyPI.

However, at the very least it might be good to

To Reproduce
Steps to reproduce the behavior:

  1. Run Packj against the following dependency: Django[argon2]

    Output:

    ===============================================
    Auditing pypi package Django[argon2] (ver: latest)
    ===============================================
    [+] Fetching 'Django[argon2]' from pypi.....FAIL [package not found!]
    =============================================
    

Expected behavior
One of:

  • Django is considered without any of its dependencies (whether or not they are core dependencies or via an extra), if that is how Packj works for other packages
  • Django (+ its 'extras') are considered
  • A friendlier warning/error is given.

Fails to find package on pypi

Describe the bug
No packages are found when scanning requirements.txt or via manual package scan.

To Reproduce

Steps to reproduce the behavior:
Run python3 main.py audit -p pypi:torch

Expected behavior
The package should be found and a report is generated.

Screenshots

python3 main.py audit -p pypi:torch
===============================================
Auditing pypi package torch (ver: latest)
===============================================
[+] Fetching 'torch' from pypi..............FAIL [package not found!]
=============================================

Desktop (please complete the following information):

  • OS: kali
  • Version 5.18.0-kali7-arm64

Unitialised variable returned by `analyze_repo_activity`

As seen here:

packj/packj/audit/main.py

Lines 454 to 470 in 0b1d391

def analyze_repo_activity(risks, report):
try:
repo_url = report['repo']['url']
msg_info('Checking repo activity...', end='', flush=True, indent=1)
reason, repo_data = git_clone(repo_url)
if reason:
alert_type = 'invalid or no source repo'
risks = alert_user(alert_type, THREAT_MODEL, reason, risks)
msg_alert(reason)
elif repo_data:
commits, contributors, tags = tuple(len(repo_data[k]) if repo_data[k] else None for k in ('commits', 'contributors', 'tags'))
msg_ok(f'commits: {commits}, contributors: {contributors}, tags: {tags}')
report['repo'].update(repo_data)
except Exception as e:
msg_fail(str(e))
finally:
return risks, report, repo_data

analyze_repo_activity()'s return value is determined by the finally: block on line 470. finally: runs regardless of the success of running the associated try:.

repo_data is set in line 458:

packj/packj/audit/main.py

Lines 458 to 459 in 0b1d391

reason, repo_data = git_clone(repo_url)
if reason:

So you can end up with:

[+]    Checking repo activity...............FAIL [[Errno 24] Too many open files: '/var/folders/45/ssw660y51fv24md76zh0w2600000gn/T/clone-_lolhhw7/django-axes/axes/locale/pl/LC_MESSAGES']
local variable 'repo_data' referenced before assignment

Obviously the git_clone call failing (output: 'Too many open files') is the underlying issue, but analyze_repo_activity()'s behaviour is a bad smell + results in extra output that may confuse some users.

Podman/Mac OSX, audit -f, getting Permission denied error /tmp/packj

Describe the bug

While testing out the container way of running packj locally on my macbook with podman I ran into this issue:

The docs say: docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help, it's also the "recommended way" currently.

When trying to audit:

podman run -v /tmp:/tmp/packj:w -it ossillate/packj:latest audit -f npm:./package.json

we get - Failed to create temp dir: [Errno 13] Permission denied: '/tmp/packj/packj_audit_dctc3110'!

Possible fixes:

  1. find out how to give the container permission to write to /tmp dir, the current User is Ubuntu, maybe we just need to give them write perms.

  2. Allow users to specify the path they want to use for writing out the audits too, in this code its currently hardcoded:

    container_mountpoint = '/tmp/packj'

it would be nice if users were able to also select where to write the audits too?

Kali VM arm64 source package not found

Describe the bug
When installing packj from the source on a Kali VM arm architecture, we are finding an issue where doing an audit, none of the packages seem to be found.
If we do a pip install, we manage to access the package through pip, and by the debug log, it seems we fail to get the manifest metadata through packj, however doing it manually through browser or curl works fine.

To Reproduce
Steps to reproduce the behavior:

  1. Download the source repo
  2. Install requirements.txt
  3. run python3 main.py audit -f pypi:requirements.txt --debug
  4. See error
β”Œβ”€β”€(rootγ‰Ώkali)-[/home/ysebyy/Desktop/packj]
└─# python3 main.py audit -f pypi:requirements.txt --debug

*** NOTE: Running in debug mode (log: /tmp/packj_audit_uiol2c12/debug_zwpua5lj.log) ***

===============================================
Auditing pypi package asttokens (ver: 2.0.5)
===============================================
[+] Fetching 'asttokens' from pypi..........FAIL [package not found!]
===============================================
Auditing pypi package dnspython (ver: 2.2.1)
===============================================
[+] Fetching 'dnspython' from pypi..........FAIL [package not found!]
===============================================
Auditing pypi package esprima (ver: 4.0.1)
===============================================
[+] Fetching 'esprima' from pypi............FAIL [package not found!]
===============================================
Auditing pypi package pyIsEmail (ver: 1.4.0)
===============================================
[+] Fetching 'pyIsEmail' from pypi..........FAIL [package not found!]
===============================================
Auditing pypi package func_timeout (ver: 4.3.5)
===============================================
[+] Fetching 'func_timeout' from pypi.......FAIL [package not found!]
===============================================
Auditing pypi package python-gitlab (ver: 2.10.1)
===============================================
[+] Fetching 'python-gitlab' from pypi......FAIL [package not found!]
===============================================
Auditing pypi package github3.py (ver: 3.2.0)
===============================================
[+] Fetching 'github3.py' from pypi.........FAIL [package not found!]
===============================================
Auditing pypi package GitPython (ver: 3.1.20)
===============================================
[+] Fetching 'GitPython' from pypi..........FAIL [package not found!]
===============================================
Auditing pypi package networkx (ver: 2.5.1)
===============================================
[+] Fetching 'networkx' from pypi...........FAIL [package not found!]
===============================================
Auditing pypi package protobuf (ver: 3.19.4)
===============================================
[+] Fetching 'protobuf' from pypi...........FAIL [package not found!]
===============================================
Auditing pypi package python_dateutil (ver: 2.8.2)
===============================================
[+] Fetching 'python_dateutil' from pypi....FAIL [package not found!]
===============================================
Auditing pypi package python_magic (ver: 0.4.26)
===============================================
[+] Fetching 'python_magic' from pypi.......FAIL [package not found!]
===============================================
Auditing pypi package pytz (ver: 2020.1)
===============================================
[+] Fetching 'pytz' from pypi...............FAIL [package not found!]
===============================================
Auditing pypi package django (ver: 4.1.1)
===============================================
[+] Fetching 'django' from pypi.............FAIL [package not found!]
===============================================
Auditing pypi package colorama (ver: 0.4.5)
===============================================
[+] Fetching 'colorama' from pypi...........FAIL [package not found!]
===============================================
Auditing pypi package rarfile (ver: 3.0)
===============================================
[+] Fetching 'rarfile' from pypi............FAIL [package not found!]
===============================================
Auditing pypi package requests (ver: 2.25.0)
===============================================
[+] Fetching 'requests' from pypi...........FAIL [package not found!]
===============================================
Auditing pypi package six (ver: 1.11.0)
===============================================
[+] Fetching 'six' from pypi................FAIL [package not found!]
===============================================
Auditing pypi package tldextract (ver: 3.1.2)
===============================================
[+] Fetching 'tldextract' from pypi.........FAIL [package not found!]
===============================================
Auditing pypi package pyyaml (ver: 6.0)
===============================================
[+] Fetching 'pyyaml' from pypi.............FAIL [package not found!]
=============================================
=> HTML summary available at: /tmp/packj_audit_uiol2c12/report_qk33185v.html

Expected behavior
Audit works and shows the output for each package

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Kali Virtual Machine

Additional context
MacOS M1 VMware ARM architecture

Debug log

Failed to parse: https://pypi.python.org/pypi/asttokens/2.0.5/json
03:32:52,277 root DEBUG fail in get_metadata for pkg dnspython, ignoring!
Failed to parse: https://pypi.python.org/pypi/dnspython/2.2.1/json
03:32:52,277 root DEBUG fail in get_metadata for pkg esprima, ignoring!
Failed to parse: https://pypi.python.org/pypi/esprima/4.0.1/json
03:32:52,278 root DEBUG fail in get_metadata for pkg pyIsEmail, ignoring!
Failed to parse: https://pypi.python.org/pypi/pyIsEmail/1.4.0/json
03:32:52,278 root DEBUG fail in get_metadata for pkg func_timeout, ignoring!
Failed to parse: https://pypi.python.org/pypi/func_timeout/4.3.5/json
03:32:52,278 root DEBUG fail in get_metadata for pkg python-gitlab, ignoring!
Failed to parse: https://pypi.python.org/pypi/python-gitlab/2.10.1/json
03:32:52,278 root DEBUG fail in get_metadata for pkg github3.py, ignoring!
Failed to parse: https://pypi.python.org/pypi/github3.py/3.2.0/json
03:32:52,278 root DEBUG fail in get_metadata for pkg GitPython, ignoring!
Failed to parse: https://pypi.python.org/pypi/GitPython/3.1.20/json
03:32:52,279 root DEBUG fail in get_metadata for pkg networkx, ignoring!
Failed to parse: https://pypi.python.org/pypi/networkx/2.5.1/json
03:32:52,279 root DEBUG fail in get_metadata for pkg protobuf, ignoring!
Failed to parse: https://pypi.python.org/pypi/protobuf/3.19.4/json
03:32:52,279 root DEBUG fail in get_metadata for pkg python_dateutil, ignoring!
Failed to parse: https://pypi.python.org/pypi/python_dateutil/2.8.2/json
03:32:52,279 root DEBUG fail in get_metadata for pkg python_magic, ignoring!
Failed to parse: https://pypi.python.org/pypi/python_magic/0.4.26/json
03:32:52,279 root DEBUG fail in get_metadata for pkg pytz, ignoring!
Failed to parse: https://pypi.python.org/pypi/pytz/2020.1/json
03:32:52,280 root DEBUG fail in get_metadata for pkg django, ignoring!
Failed to parse: https://pypi.python.org/pypi/django/4.1.1/json
03:32:52,280 root DEBUG fail in get_metadata for pkg colorama, ignoring!
Failed to parse: https://pypi.python.org/pypi/colorama/0.4.5/json
03:32:52,280 root DEBUG fail in get_metadata for pkg rarfile, ignoring!
Failed to parse: https://pypi.python.org/pypi/rarfile/3.0/json
03:32:52,280 root DEBUG fail in get_metadata for pkg requests, ignoring!
Failed to parse: https://pypi.python.org/pypi/requests/2.25.0/json
03:32:52,280 root DEBUG fail in get_metadata for pkg six, ignoring!
Failed to parse: https://pypi.python.org/pypi/six/1.11.0/json
03:32:52,280 root DEBUG fail in get_metadata for pkg tldextract, ignoring!
Failed to parse: https://pypi.python.org/pypi/tldextract/3.1.2/json
03:32:52,281 root DEBUG fail in get_metadata for pkg pyyaml, ignoring!
Failed to parse: https://pypi.python.org/pypi/pyyaml/6.0/json

Curl works to these packages

{"info":{"author":"Kirill Simonov","author_email":"[email protected]"

However, it seems to throw a 302 redirect with the -L flag, so maybe that's the issue here.

Support for Github tokens

Is your feature request related to a problem? Please describe.
Github token will increase the limits. However, Packj currently doesn't support a way to pass that.

Describe the solution you'd like
We can add support for this: e.g., specify token in .packj.yaml

Ruby 3 not supported

Run bundle install
Get "Your Ruby version is 3.1.2, but your Gemfile specified 2.5.1"

Failed to parse rules in packj.yaml: module 'lib' has no attribute 'X509_V_FLAG_CB_ISSUER_CHECK'

Describe the bug

  • Did not run this on docker.
  • Cannot run sandbox tool after following the instructions. This is the error message:
    Failed to parse rules in packj.yaml: module 'lib' has no attribute 'X509_V_FLAG_CB_ISSUER_CHECK'
  • Cannot run pip -V or pip list after installing sudo pip -r requirements.txt. Here is the error when I run pip -V:
Traceback (most recent call last):
  File "/usr/bin/pip", line 11, in <module>
    load_entry_point('pip==20.0.2', 'console_scripts', 'pip')()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 490, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2854, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2445, in load
    return self.resolve()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2451, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/main.py", line 10, in <module>
    from pip._internal.cli.autocompletion import autocomplete
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/autocompletion.py", line 9, in <module>
    from pip._internal.cli.main_parser import create_main_parser
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/main_parser.py", line 7, in <module>
    from pip._internal.cli import cmdoptions
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/cmdoptions.py", line 24, in <module>
    from pip._internal.exceptions import CommandError
  File "/usr/lib/python3/dist-packages/pip/_internal/exceptions.py", line 10, in <module>
    from pip._vendor.six import iteritems
  File "/usr/lib/python3/dist-packages/pip/_vendor/__init__.py", line 65, in <module>
    vendored("cachecontrol")
  File "/usr/lib/python3/dist-packages/pip/_vendor/__init__.py", line 36, in vendored
    __import__(modulename, globals(), locals(), level=0)
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl/cachecontrol/__init__.py", line 9, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl/cachecontrol/wrapper.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl/cachecontrol/adapter.py", line 5, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/requests-2.22.0-py2.py3-none-any.whl/requests/__init__.py", line 95, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/urllib3-1.25.8-py2.py3-none-any.whl/urllib3/contrib/pyopenssl.py", line 46, in <module>
  File "/usr/lib/python3/dist-packages/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import crypto, SSL
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 1553, in <module>
    class X509StoreFlags(object):
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 1573, in X509StoreFlags
    CB_ISSUER_CHECK = _lib.X509_V_FLAG_CB_ISSUER_CHECK
AttributeError: module 'lib' has no attribute 'X509_V_FLAG_CB_ISSUER_CHECK'
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 72, in apport_excepthook
    from apport.fileutils import likely_packaged, get_recent_crashes
  File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
    from apport.report import Report
  File "/usr/lib/python3/dist-packages/apport/report.py", line 32, in <module>
    import apport.fileutils
  File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 12, in <module>
    import os, glob, subprocess, os.path, time, pwd, sys, requests_unixsocket
  File "/usr/lib/python3/dist-packages/requests_unixsocket/__init__.py", line 1, in <module>
    import requests
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/requests-2.22.0-py2.py3-none-any.whl/requests/__init__.py", line 95, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/urllib3-1.25.8-py2.py3-none-any.whl/urllib3/contrib/pyopenssl.py", line 46, in <module>
  File "/usr/lib/python3/dist-packages/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import crypto, SSL
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 1553, in <module>
    class X509StoreFlags(object):
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 1573, in X509StoreFlags
    CB_ISSUER_CHECK = _lib.X509_V_FLAG_CB_ISSUER_CHECK
AttributeError: module 'lib' has no attribute 'X509_V_FLAG_CB_ISSUER_CHECK'

Original exception was:
Traceback (most recent call last):
  File "/usr/bin/pip", line 11, in <module>
    load_entry_point('pip==20.0.2', 'console_scripts', 'pip')()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 490, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2854, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2445, in load
    return self.resolve()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2451, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/main.py", line 10, in <module>
    from pip._internal.cli.autocompletion import autocomplete
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/autocompletion.py", line 9, in <module>
    from pip._internal.cli.main_parser import create_main_parser
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/main_parser.py", line 7, in <module>
    from pip._internal.cli import cmdoptions
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/cmdoptions.py", line 24, in <module>
    from pip._internal.exceptions import CommandError
  File "/usr/lib/python3/dist-packages/pip/_internal/exceptions.py", line 10, in <module>
    from pip._vendor.six import iteritems
  File "/usr/lib/python3/dist-packages/pip/_vendor/__init__.py", line 65, in <module>
    vendored("cachecontrol")
  File "/usr/lib/python3/dist-packages/pip/_vendor/__init__.py", line 36, in vendored
    __import__(modulename, globals(), locals(), level=0)
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl/cachecontrol/__init__.py", line 9, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl/cachecontrol/wrapper.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl/cachecontrol/adapter.py", line 5, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/requests-2.22.0-py2.py3-none-any.whl/requests/__init__.py", line 95, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "/usr/share/python-wheels/urllib3-1.25.8-py2.py3-none-any.whl/urllib3/contrib/pyopenssl.py", line 46, in <module>
  File "/usr/lib/python3/dist-packages/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import crypto, SSL
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 1553, in <module>
    class X509StoreFlags(object):
  File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 1573, in X509StoreFlags
    CB_ISSUER_CHECK = _lib.X509_V_FLAG_CB_ISSUER_CHECK
AttributeError: module 'lib' has no attribute 'X509_V_FLAG_CB_ISSUER_CHECK'

To Reproduce

  • Steps to reproduce the behavior:
    sudo python3 main.py sandbox npm install express

OS:

  • OS: Ubuntu Linux and WSL for Windows

Detection capability for local Node.js projects

Is your feature request related to a problem? Please describe.
I'm doing some research about supply chain attacks happened in the ecosystem of Node.js and I use packj to analyze malicious samples which have been removed from npmjs's official registry.

Actually, there are also other occasions when developers want to analyze some packages that not managed on the official registry. For example, some Node.js applications that directly released on GitHub. Therefore, capability to detect malicious behavior for local projects are also beneficial.

Describe the solution you'd like
I hope I can use the following command to audit a local project

$python3 main.py audit -p npm:/path/to/node/project

Describe alternatives you've considered
I'm refactoring the pm_proxy of npmjs in my forked repo in order to support the capability of local analysis.

Additional context
If you think it a good idea, we can discuss further more in this issue and I'm willing to contribute for the local detection capability on js. If you are not interested in this new feature, it's ok for me and I will just modify the code to fit only my specific needs.

Discord invite is invalid

Hello,

Cool project! I wanted to see how I could contribute but could not join the discord due to the invalid invite link.
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.