python dependency vulnerability scanner, written in Rust.

Overview

🐍 Pyscan

CI Liscense PyPI GitHub issues Top Language

A dependency vulnerability scanner for your python projects, straight from the terminal.
  • 🚀 blazingly fast scanner that can be used within large projects quickly.
  • 🤖 automatically uses requirements.txt, pyproject.toml or, the source code.
  • 🧑‍💻 can be integrated into existing build processes.
  • 💽 In its alpha stage, some features may not work correctly. PRs and issue makers welcome.

🕊️ Install

> pip install pyscan-rs

look out for the "-rs" part or

> cargo install pyscan

check out the releases.

🐇 Usage

Go to your python source directory (or wherever you keep your requirements.txt/pyproject.toml) and run:

> pyscan

or

> pyscan -d path/to/src

Docker

Pyscan can scan inside docker images given you provide the correct path inside. This is still in its early stage and may break easily.

> pyscan docker -n my-docker-image -p /path/inside/container/to/source

by "source" I mean requirements.txt, pyproject.toml or your python files. Note: Your docker engine/daemon should be running as pyscan utilizes the docker create command.


Here's the order of precedence for a "source" file:
  • requirements.txt
  • pyproject.toml
  • your python source code (.py) [highly discouraged]

Pyscan will find dependency versions from pip if not provided within the source file. Even though, Make sure you version-ize your requirements and use proper pep-508 syntax.

🦀 Note

pyscan uses OSV as its database for now. There are plans to add a few more.

pyscan doesn't make sure your code is safe from everything. Use all resources available to you like Dependabot, pip-audit or trivy.

🐰 Todo

  • get it working.
  • add tests. [coming soon]
  • query individual python packages. [v0.1.1]
  • perfomance optimizations.
  • scan docker images [v0.1.2]
  • scan code health. [coming soon]

🐹 Sponsor

While not coding, I am a broke high school student with nothing else to do. I appreciate all the help I can get.

Comments
  • Crashing on my machine

    Crashing on my machine

    Python 3.11 in a conda environment on Windows, pip installed pyscan-rs:

    pyscan v0.1.3 | by Aswin (github.com/aswinnnn)
    Found 9 dependencies...
    |-| fasteners [0.18] -> No vulnerabilities found.
    thread 'main' panicked at 'Could not retrive package version.: PipError("could not retrive package version from Pip")', src\scanner\mod.rs:28:69
    stack backtrace:
       0:           0x973780 - <unknown>
       1:           0x9cbc1b - <unknown>
       2:           0x965605 - <unknown>
       3:           0x97698f - <unknown>
       4:           0x976647 - <unknown>
       5:           0x9771bf - <unknown>
       6:           0x9770c5 - <unknown>
       7:           0x9742bf - <unknown>
       8:           0x976de0 - <unknown>
       9:           0x9c86a5 - <unknown>
      10:           0x9c8a73 - <unknown>
      11:           0x422bc9 - <unknown>
      12:           0x42ebf8 - <unknown>
      13:           0x4410a5 - <unknown>
      14:           0x447be6 - <unknown>
      15:           0x41cecc - <unknown>
      16:           0x958097 - <unknown>
      17:           0x44524d - <unknown>
      18:           0x4013f8 - <unknown>
      19:           0x40151b - <unknown>
      20:     0x7ffffab07614 - <unknown>
      21:     0x7ffffc0a26a1 - <unknown>
    

    Any idea?

    bug 
    opened by ArneBachmannDLR 8
  • Incorrect version detection of requests package

    Incorrect version detection of requests package

    Describe the bug When running pyscan does tell me there is a vulnerability in my requests dependency, although the version that is specified is not the version that is installed. In the installed version this vulnerability has been patched.

    I am getting the following result back after running pyscan:

    pyscan v0.1.1 | by Aswin (github.com/aswinnnn)
    Found 6 dependencies...
    |-| netaddr [0.8.0] -> No vulnerabilities found.
    |-| defusedxml [0.7.1] -> No vulnerabilities found.
    |-| dnspython [2.3.0rc1] -> No vulnerabilities found.
    |-| pandas [2.0.1] -> No vulnerabilities found.
    |-| requests [2.9.2] -> Found vulnerabilities!
    |-| python-evtx [0.7.4] -> No vulnerabilities found.
    SUMMARY
    
    Dependency: requests
    ID: GHSA-x84v-xcm2-53pg
    Details: The Requests package through 2.19.1 before 2018-09-14 for Python sends an HTTP Authorization header to an http URI upon receiving a same-hostname https-to-http redirect, which makes it easier for remote attackers to discover credentials by sniffing the network.
    Versions affected: 0.0.1 to 2.9.2
    
    Dependency: requests
    ID: PYSEC-2018-28
    Details: The Requests package before 2.20.0 for Python sends an HTTP Authorization header to an http URI upon receiving a same-hostname https-to-http redirect, which makes it easier for remote attackers to discover credentials by sniffing the network.
    Versions affected: 0.0.1 to 2.9.2
    

    Running a pip3 freeze yields:

    defusedxml==0.7.1
    dnspython==2.3.0
    netaddr==0.8.0
    pandas==2.0.1
    pyscan-rs==0.1.1
    python-evtx==0.7.4
    requests==2.30.0
    

    Yet when running pyscan package -n requests -v 2.30.0 I am getting the expected response:

    Found 1 dependencies...
    |-| requests [2.30.0] -> No vulnerabilities found.
    

    To Reproduce Steps to reproduce the behavior:

    1. Create a vritual environment
    2. Install the following requirements.txt:
      netaddr
      defusedxml
      dnspython
      pandas
      requests
      python-evtx
      
    3. Run pip3 install pyscan-rs
    4. Scanning the project: pyscan

    Expected behavior It is expected that the version number of the currently installed package is identified correctly.

    Desktop (please complete the following information):

    • OS: macOS Ventura
    bug good first issue 
    opened by anotherbridge 4
  • Exit with zero in case of vulnerability found

    Exit with zero in case of vulnerability found

    Describe the bug When a vulnerability was found the exit code of the program is zero. Thus it makes it hard to integrate the tool into an automation that should raise an alert in case a vulnerability was found. This is the case when running pyscan either for a specific package or within a repository.

    To Reproduce Steps to reproduce the behavior:

    1. Run pyscan package -n requests -v 2.30.0
    2. Run echo $?
    3. Observe that 0 is returned

    Expected behavior It is expected that a non-zero exit code is returned in case a vulnerability is found.

    Desktop (please complete the following information):

    • OS: macOS Ventura ARM architecture, Debian 11.7 x86 architecture
    opened by anotherbridge 1
  • Use batch API for OSV

    Use batch API for OSV

    pyscan is very slow for a repo with 429 3rd-party packages (which is claimed to be the #1 feature of pyscan according to the homepage). If I am not mistaken, it makes one HTTP request to the OSV API per scanned packages despite the fact that we know all scanned packages and versions in advance. OSV as a batch API which could be leveraged to make pyscan IMO much faster: https://google.github.io/osv.dev/post-v1-querybatch/

    BTW: What is the added value of Rust in app that just parses a text file, makes a HTTP call and formats the results? Compiling the pyscan-rs takes ages and perhaps a pure Python code could be fast enough?

    enhancement question 
    opened by sarimak 4
  • Add support for constraints.txt

    Add support for constraints.txt

    Names and version of Python packages can be specified also in a constraints.txt file and pyscan doesn't detect it by name. Please search also for constraints.txt in addition to requirements.txt.

    Workaround: ln -s constraints.txt requirements.txt; pyscan (both files use the same syntax)

    Context: A monorepo containing several Python packages which need to be installable into the same virtual environment needs a central place for pinning the 3rd-party package versions (in addition to per-package setup.cfg/pyproject.toml). There is a standard mechanism for that: https://pip.pypa.io/en/stable/user_guide/#constraints-files

    enhancement 
    opened by sarimak 1
  • prompt/default to when dependency conflict occurs

    prompt/default to when dependency conflict occurs

    Describe the bug Although #1 is now fixed, I still encountered a similar issue that I didn't recognize before (since I didn't test this case). When a minimum version is specified in the requirements.txt, then the tool will take the version that is specified instead of checking which version is actually used.

    To Reproduce Steps to reproduce the behavior:

    1. Install the following requirements file into a separate environment:
      pandas>=1.5.0
      requests>=2.30.0
      beautifulsoup4>=4.12.2
      lxml>=4.9.2
      
    2. Run pip freeze to investigate the installed versions:
      pandas==2.0.1
      requests==2.31.0
      beautifulsoup4==4.12.2
      lxml==4.9.2
      
    3. Run pyscan and investigate the output:
      pyscan v0.1.3 | by Aswin (github.com/aswinnnn)
      Found 4 dependencies...
      |-| pandas [1.5.0] -> No vulnerabilities found.
      |-| requests [2.30.0] -> Found vulnerabilities!
      |-| beautifulsoup4 [4.12.2] -> No vulnerabilities found.
      |-| lxml [4.9.2] -> No vulnerabilities found.
      SUMMARY
      ...
      

    Expected behavior The version number of the currently installed packages should be taken instead of the minimum required version specified in the requirements.txt file.

    Desktop (please complete the following information):

    • OS: macOS Ventura ARM architecture

    pyscan version v0.1.3

    enhancement 
    opened by anotherbridge 9
Releases(v0.1.3)
Owner
Aswin.
I like computers and I mess with stuff.
Aswin.
Rust Imaging Library's Python binding: A performant and high-level image processing library for Python written in Rust

ril-py Rust Imaging Library for Python: Python bindings for ril, a performant and high-level image processing library written in Rust. What's this? Th

Cryptex 13 Dec 6, 2022
LOKI2 - Simple IOC and YARA Scanner

LOKI2 LOKI - Simple IOC and YARA Scanner Status Work in Progress. This version is not ready for use. There's still some work to do for a first release

Florian Roth 34 Dec 20, 2022
High-Speed Memory Scanner & Analyzer with REST API.

memory-server High-Speed Memory Scanner & Analyzer with REST API. Usage iOS Jailbreaking of iphone is required. Place your PC and iphone in the same n

Kenjiro Ichise 8 Jul 12, 2023
zero-dependency 3d math library in rust

dualquat A lightweight, zero-dependency 3d math library for use in Dual Quaternion based physics simulation. Capable of representing and transforming

null 4 Nov 11, 2022
Dynamic dependency injection library for rust.

DDI (dynamic dependency injection) This library provides a generic dependency injection container that can be easily integrated into any application a

EYHN 34 Feb 21, 2023
Rudi - an out-of-the-box dependency injection framework for Rust.

Rudi Rudi - an out-of-the-box dependency injection framework for Rust. use rudi::{Context, Singleton, Transient}; // Register `fn(cx) -> A { A }` as

ZihanType 15 Aug 15, 2023
A zero-dependency crate for writing repetitive code easier and faster.

akin A zero-dependency crate for writing repetitive code easier and faster. Check Syntax for information about how to use it. Why? Example Syntax NONE

LyonSyonII 36 Dec 29, 2022
A truly zero-dependency crate providing quick, easy, reliable, and scalable access to the name "jordin"

jordin Finally! A truly zero-dependency crate providing quick, easy, reliable, and scalable access to the name "jordin". Additionally, this one-of-a-k

jordin 2 Aug 4, 2022
Track and query Cargo dependency graphs.

cargo-guppy: track and query dependency graphs This repository contains the source code for: guppy: a library for performing queries on Cargo dependen

guppy 42 Dec 30, 2022
A lightweight, zero-dependency struct diffing library which allows changed fields to be collected and applied

structdiff A lightweight, zero-dependency struct diffing library which allows changed fields to be collected and applied. Derive Difference on a struc

null 7 Dec 25, 2022
Generate a dependency list to thank them on README.

thanks-dependencies This generates list of dependencies. I think it's better to publish dependencies explicitly on documentation. Of course users can

keiya sasaki 7 Jan 30, 2023
A high-performance WebSocket integration library for streaming public market data. Used as a key dependency of the `barter-rs` project.

Barter-Data A high-performance WebSocket integration library for streaming public market data from leading cryptocurrency exchanges - batteries includ

Barter 23 Feb 3, 2023
Fast DNA manipulation for Python, written in Rust.

quickdna Quickdna is a simple, fast library for working with DNA sequences. It is up to 100x faster than Biopython for some translation tasks, in part

Secure DNA 22 Dec 31, 2022
This is a simple command line application to convert bibtex to json written in Rust and Python

bibtex-to-json This is a simple command line application to convert bibtex to json written in Rust and Python. Why? To enable you to convert very big

null 3 Mar 23, 2022
Fuzzy Index for Python, written in Rust. Works like error-tolerant dict, keyed by a human input.

FuzzDex FuzzDex is a fast Python library, written in Rust. It implements an in-memory fuzzy index that works like an error-tolerant dictionary keyed b

Tomasz bla Fortuna 8 Dec 15, 2022
📦 A Python package manager written in Rust inspired by Cargo.

huak About A Python package manager written in Rust. The Cargo for Python. ⚠️ Disclaimer: huak is currently in its proof-of-concept (PoC) phase. Huak

Chris Pryer 186 Jan 9, 2023
📦 A Python package manager written in Rust inspired by Cargo.

huak About A Python package manager written in Rust. The Cargo for Python. ⚠️ Disclaimer: huak is currently in its Alpha phase. Huak aims to support a

Chris Pryer 161 Oct 9, 2022
An extremely fast Python linter, written in Rust.

Ruff An extremely fast Python linter, written in Rust. Linting the CPython codebase from scratch. ⚡️ 10-100x faster than existing linters ?? Installab

Charlie Marsh 5.1k Dec 30, 2022
⚡ Blazing fast async/await HTTP client for Python written on Rust using reqwests

Reqsnaked Reqsnaked is a blazing fast async/await HTTP client for Python written on Rust using reqwests. Works 15% faster than aiohttp on average RAII

Yan Kurbatov 8 Mar 2, 2023