pysentry-rs 0.1.4__cp310-cp310-macosx_11_0_arm64.whl → 0.2.0__cp310-cp310-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pysentry-rs might be problematic. Click here for more details.
- pysentry/__init__.py +88 -62
- pysentry/_internal.cpython-310-darwin.so +0 -0
- pysentry_rs-0.2.0.dist-info/METADATA +562 -0
- pysentry_rs-0.2.0.dist-info/RECORD +8 -0
- pysentry_rs-0.1.4.dist-info/METADATA +0 -376
- pysentry_rs-0.1.4.dist-info/RECORD +0 -8
- {pysentry_rs-0.1.4.dist-info → pysentry_rs-0.2.0.dist-info}/WHEEL +0 -0
- {pysentry_rs-0.1.4.dist-info → pysentry_rs-0.2.0.dist-info}/entry_points.txt +0 -0
- {pysentry_rs-0.1.4.dist-info → pysentry_rs-0.2.0.dist-info}/licenses/LICENSE +0 -0
pysentry/__init__.py
CHANGED
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
from ._internal import audit_python, audit_with_options, check_resolvers, check_version
|
|
4
4
|
|
|
5
|
-
__version__ = "0.
|
|
6
|
-
__all__ = [
|
|
5
|
+
__version__ = "0.2.0"
|
|
6
|
+
__all__ = [
|
|
7
|
+
"audit_python",
|
|
8
|
+
"audit_with_options",
|
|
9
|
+
"check_resolvers",
|
|
10
|
+
"check_version",
|
|
11
|
+
"main",
|
|
12
|
+
]
|
|
7
13
|
|
|
8
14
|
|
|
9
15
|
def main():
|
|
@@ -11,73 +17,83 @@ def main():
|
|
|
11
17
|
import sys
|
|
12
18
|
import argparse
|
|
13
19
|
|
|
14
|
-
# Handle
|
|
15
|
-
if len(sys.argv) > 1
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
20
|
+
# Handle subcommands manually to match Rust CLI structure exactly
|
|
21
|
+
if len(sys.argv) > 1:
|
|
22
|
+
if sys.argv[1] == "resolvers":
|
|
23
|
+
# Resolvers subcommand
|
|
24
|
+
parser = argparse.ArgumentParser(
|
|
25
|
+
prog="pysentry resolvers",
|
|
26
|
+
description="Check available dependency resolvers",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
args = parser.parse_args(sys.argv[2:])
|
|
33
|
+
try:
|
|
34
|
+
result = check_resolvers(args.verbose)
|
|
35
|
+
print(result)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
elif sys.argv[1] == "check-version":
|
|
42
|
+
# Check-version subcommand
|
|
43
|
+
parser = argparse.ArgumentParser(
|
|
44
|
+
prog="pysentry-rs check-version",
|
|
45
|
+
description="Check if a newer version is available",
|
|
46
|
+
)
|
|
47
|
+
parser.add_argument(
|
|
48
|
+
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
args = parser.parse_args(sys.argv[2:])
|
|
52
|
+
try:
|
|
53
|
+
result = check_version(args.verbose)
|
|
54
|
+
print(result)
|
|
55
|
+
except Exception as e:
|
|
56
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
return
|
|
59
|
+
elif sys.argv[1] in ["-h", "--help"]:
|
|
60
|
+
# Show main help
|
|
61
|
+
pass
|
|
62
|
+
elif sys.argv[1] in ["-V", "--version"]:
|
|
63
|
+
print(f"pysentry-rs {__version__}")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
# Main parser for audit command (default) and help
|
|
59
67
|
parser = argparse.ArgumentParser(
|
|
60
68
|
prog="pysentry-rs",
|
|
61
69
|
description="Security vulnerability auditing for Python packages",
|
|
70
|
+
usage="pysentry-rs [OPTIONS] [PATH] [COMMAND]",
|
|
62
71
|
)
|
|
63
72
|
|
|
73
|
+
# Add version argument
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"-V", "--version", action="version", version=f"pysentry-rs {__version__}"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Main audit arguments
|
|
64
79
|
parser.add_argument(
|
|
65
80
|
"path",
|
|
66
81
|
nargs="?",
|
|
67
82
|
default=".",
|
|
68
|
-
|
|
83
|
+
metavar="PATH",
|
|
84
|
+
help="Path to the project directory to audit [default: .]",
|
|
69
85
|
)
|
|
70
86
|
parser.add_argument(
|
|
71
87
|
"--format",
|
|
72
88
|
choices=["human", "json", "sarif"],
|
|
73
89
|
default="human",
|
|
74
|
-
help="Output format
|
|
90
|
+
help="Output format [default: human] [possible values: human, json, sarif]",
|
|
75
91
|
)
|
|
76
92
|
parser.add_argument(
|
|
77
93
|
"--severity",
|
|
78
94
|
choices=["low", "medium", "high", "critical"],
|
|
79
95
|
default="low",
|
|
80
|
-
help="Minimum severity level to report
|
|
96
|
+
help="Minimum severity level to report [default: low] [possible values: low, medium, high, critical]",
|
|
81
97
|
)
|
|
82
98
|
parser.add_argument(
|
|
83
99
|
"--ignore",
|
|
@@ -87,13 +103,12 @@ def main():
|
|
|
87
103
|
help="Vulnerability IDs to ignore (can be specified multiple times)",
|
|
88
104
|
)
|
|
89
105
|
parser.add_argument(
|
|
90
|
-
"
|
|
106
|
+
"-o", "--output", metavar="FILE", help="Output file path (defaults to stdout)"
|
|
91
107
|
)
|
|
92
108
|
parser.add_argument(
|
|
93
|
-
"--
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"--optional", action="store_true", help="Include optional dependencies"
|
|
109
|
+
"--all",
|
|
110
|
+
action="store_true",
|
|
111
|
+
help="Include ALL dependencies (main + dev, optional, etc)",
|
|
97
112
|
)
|
|
98
113
|
parser.add_argument(
|
|
99
114
|
"--direct-only",
|
|
@@ -106,13 +121,13 @@ def main():
|
|
|
106
121
|
"--source",
|
|
107
122
|
choices=["pypa", "pypi", "osv"],
|
|
108
123
|
default="pypa",
|
|
109
|
-
help="Vulnerability data source
|
|
124
|
+
help="Vulnerability data source [default: pypa] [possible values: pypa, pypi, osv]",
|
|
110
125
|
)
|
|
111
126
|
parser.add_argument(
|
|
112
127
|
"--resolver",
|
|
113
128
|
choices=["uv", "pip-tools"],
|
|
114
129
|
default="uv",
|
|
115
|
-
help="Dependency resolver for requirements.txt files
|
|
130
|
+
help="Dependency resolver for requirements.txt files [default: uv] [possible values: uv, pip-tools]",
|
|
116
131
|
)
|
|
117
132
|
parser.add_argument(
|
|
118
133
|
"--requirements-files",
|
|
@@ -121,16 +136,27 @@ def main():
|
|
|
121
136
|
help="Specific requirements files to audit (disables auto-discovery)",
|
|
122
137
|
)
|
|
123
138
|
parser.add_argument(
|
|
124
|
-
"
|
|
139
|
+
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
125
140
|
)
|
|
126
141
|
parser.add_argument(
|
|
127
|
-
"
|
|
142
|
+
"-q", "--quiet", action="store_true", help="Suppress non-error output"
|
|
128
143
|
)
|
|
129
144
|
|
|
145
|
+
# Add custom help text for commands
|
|
146
|
+
parser.epilog = """
|
|
147
|
+
Commands:
|
|
148
|
+
resolvers Check available dependency resolvers
|
|
149
|
+
check-version Check if a newer version is available
|
|
150
|
+
help Print this message or the help of the given subcommand(s)
|
|
151
|
+
"""
|
|
152
|
+
|
|
130
153
|
args = parser.parse_args()
|
|
131
154
|
|
|
132
155
|
try:
|
|
133
|
-
# Main audit functionality
|
|
156
|
+
# Main audit functionality - convert --all to dev/optional
|
|
157
|
+
dev = args.all
|
|
158
|
+
optional = args.all
|
|
159
|
+
|
|
134
160
|
result = audit_with_options(
|
|
135
161
|
path=args.path,
|
|
136
162
|
format=args.format,
|
|
@@ -138,8 +164,8 @@ def main():
|
|
|
138
164
|
min_severity=args.severity,
|
|
139
165
|
ignore_ids=args.ignore_ids,
|
|
140
166
|
output=args.output,
|
|
141
|
-
dev=
|
|
142
|
-
optional=
|
|
167
|
+
dev=dev,
|
|
168
|
+
optional=optional,
|
|
143
169
|
direct_only=args.direct_only,
|
|
144
170
|
no_cache=args.no_cache,
|
|
145
171
|
cache_dir=args.cache_dir,
|
|
Binary file
|
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pysentry-rs
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
7
|
+
Classifier: Programming Language :: Rust
|
|
8
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Topic :: Security
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Summary: Security vulnerability auditing tool for Python packages
|
|
19
|
+
Author-email: nyudenkov <nyudenkov@pm.me>
|
|
20
|
+
License: GPL-3.0
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
23
|
+
Project-URL: Homepage, https://github.com/nyudenkov/pysentry
|
|
24
|
+
Project-URL: Repository, https://github.com/nyudenkov/pysentry
|
|
25
|
+
Project-URL: Issues, https://github.com/nyudenkov/pysentry/issues
|
|
26
|
+
|
|
27
|
+
# 🐍 PySentry
|
|
28
|
+
|
|
29
|
+
[Help to test and improve](https://github.com/nyudenkov/pysentry/issues/12)
|
|
30
|
+
|
|
31
|
+
A fast, reliable security vulnerability scanner for Python projects, written in Rust.
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
36
|
+
|
|
37
|
+
## Key Features
|
|
38
|
+
|
|
39
|
+
- **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `pyproject.toml`, and `requirements.txt` files
|
|
40
|
+
- **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
|
|
41
|
+
- **Multiple Data Sources**:
|
|
42
|
+
- PyPA Advisory Database (default)
|
|
43
|
+
- PyPI JSON API
|
|
44
|
+
- OSV.dev (Open Source Vulnerabilities)
|
|
45
|
+
- **Flexible Output**: Human-readable, JSON, and SARIF formats
|
|
46
|
+
- **Performance Focused**:
|
|
47
|
+
- Written in Rust for speed
|
|
48
|
+
- Async/concurrent processing
|
|
49
|
+
- Intelligent caching system
|
|
50
|
+
- **Comprehensive Filtering**:
|
|
51
|
+
- Severity levels (low, medium, high, critical)
|
|
52
|
+
- Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
|
|
53
|
+
- Direct vs. transitive dependencies
|
|
54
|
+
- **Enterprise Ready**: SARIF output for IDE/CI integration
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
Choose the installation method that works best for you:
|
|
59
|
+
|
|
60
|
+
### ⚡ Via uvx (Recommended for occasional use)
|
|
61
|
+
|
|
62
|
+
Run directly without installing (requires [uv](https://docs.astral.sh/uv/)):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uvx pysentry-rs /path/to/project
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This method:
|
|
69
|
+
|
|
70
|
+
- Runs the latest version without installation
|
|
71
|
+
- Automatically manages Python environment
|
|
72
|
+
- Perfect for CI/CD or occasional security audits
|
|
73
|
+
- No need to manage package versions or updates
|
|
74
|
+
|
|
75
|
+
### 📦 From PyPI (Python Package)
|
|
76
|
+
|
|
77
|
+
For Python 3.8+ on Linux and macOS:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install pysentry-rs
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Then use it with Python:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
python -m pysentry /path/to/project
|
|
87
|
+
# or directly if scripts are in PATH
|
|
88
|
+
pysentry-rs /path/to/project
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### ⚡ From Crates.io (Rust Package)
|
|
92
|
+
|
|
93
|
+
If you have Rust installed:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cargo install pysentry
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 💾 From GitHub Releases (Pre-built Binaries)
|
|
100
|
+
|
|
101
|
+
Download the latest release for your platform:
|
|
102
|
+
|
|
103
|
+
- **Linux x64**: `pysentry-linux-x64.tar.gz`
|
|
104
|
+
- **Linux x64 (musl)**: `pysentry-linux-x64-musl.tar.gz`
|
|
105
|
+
- **Linux ARM64**: `pysentry-linux-arm64.tar.gz`
|
|
106
|
+
- **macOS x64**: `pysentry-macos-x64.tar.gz`
|
|
107
|
+
- **macOS ARM64**: `pysentry-macos-arm64.tar.gz`
|
|
108
|
+
- **Windows x64**: `pysentry-windows-x64.zip`
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Example for Linux x64
|
|
112
|
+
curl -L https://github.com/nyudenkov/pysentry/releases/latest/download/pysentry-linux-x64.tar.gz | tar -xz
|
|
113
|
+
./pysentry-linux-x64/pysentry --help
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 🔧 From Source
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
git clone https://github.com/nyudenkov/pysentry
|
|
120
|
+
cd pysentry
|
|
121
|
+
cargo build --release
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The binary will be available at `target/release/pysentry`.
|
|
125
|
+
|
|
126
|
+
### Requirements
|
|
127
|
+
|
|
128
|
+
- **For uvx**: Python 3.8+ and [uv](https://docs.astral.sh/uv/) installed (Linux/macOS only)
|
|
129
|
+
- **For binaries**: No additional dependencies
|
|
130
|
+
- **For Python package**: Python 3.8+ (Linux/macOS only)
|
|
131
|
+
- **For Rust package and source**: Rust 1.79+
|
|
132
|
+
|
|
133
|
+
### Platform Support
|
|
134
|
+
|
|
135
|
+
| Installation Method | Linux | macOS | Windows |
|
|
136
|
+
| ------------------- | ----- | ----- | ------- |
|
|
137
|
+
| uvx | ✅ | ✅ | ❌ |
|
|
138
|
+
| PyPI (pip) | ✅ | ✅ | ❌ |
|
|
139
|
+
| Crates.io (cargo) | ✅ | ✅ | ✅ |
|
|
140
|
+
| GitHub Releases | ✅ | ✅ | ✅ |
|
|
141
|
+
| From Source | ✅ | ✅ | ✅ |
|
|
142
|
+
|
|
143
|
+
**Note**: Windows Python wheels are not available due to compilation complexity. Windows users should use the pre-built binary from GitHub releases, install via cargo and build from source.
|
|
144
|
+
|
|
145
|
+
### CLI Command Names
|
|
146
|
+
|
|
147
|
+
- **Rust binary**: `pysentry` (when installed via cargo or binary releases)
|
|
148
|
+
- **Python package**: `pysentry-rs` (when installed via pip or uvx)
|
|
149
|
+
|
|
150
|
+
Both variants support identical functionality. The resolver tools (`uv`, `pip-tools`) must be available in your current environment regardless of which PySentry variant you use.
|
|
151
|
+
|
|
152
|
+
### Requirements.txt Support Prerequisites
|
|
153
|
+
|
|
154
|
+
To scan `requirements.txt` files, PySentry requires an external dependency resolver to convert version constraints (e.g., `flask>=2.0,<3.0`) into exact versions for vulnerability scanning.
|
|
155
|
+
|
|
156
|
+
**Install a supported resolver:**
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# uv (recommended - fastest, Rust-based)
|
|
160
|
+
pip install uv
|
|
161
|
+
|
|
162
|
+
# pip-tools (widely compatible, Python-based)
|
|
163
|
+
pip install pip-tools
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Environment Requirements:**
|
|
167
|
+
|
|
168
|
+
- Resolvers must be available in your current environment
|
|
169
|
+
- If using virtual environments, activate your venv before running PySentry:
|
|
170
|
+
```bash
|
|
171
|
+
source venv/bin/activate # Linux/macOS
|
|
172
|
+
venv\Scripts\activate # Windows
|
|
173
|
+
pysentry /path/to/project
|
|
174
|
+
```
|
|
175
|
+
- Alternatively, install resolvers globally for system-wide availability
|
|
176
|
+
|
|
177
|
+
**Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `poetry.lock` files can be scanned.
|
|
178
|
+
|
|
179
|
+
## Quick Start
|
|
180
|
+
|
|
181
|
+
### Basic Usage
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Using uvx (recommended for occasional use)
|
|
185
|
+
uvx pysentry-rs
|
|
186
|
+
uvx pysentry-rs /path/to/python/project
|
|
187
|
+
|
|
188
|
+
# Using installed binary
|
|
189
|
+
pysentry
|
|
190
|
+
pysentry /path/to/python/project
|
|
191
|
+
|
|
192
|
+
# Automatically detects project type (uv.lock, poetry.lock, pyproject.toml, requirements.txt)
|
|
193
|
+
pysentry /path/to/project
|
|
194
|
+
|
|
195
|
+
# Force specific resolver
|
|
196
|
+
pysentry --resolver uv /path/to/project
|
|
197
|
+
pysentry --resolver pip-tools /path/to/project
|
|
198
|
+
|
|
199
|
+
# Include all dependencies (main + dev + optional)
|
|
200
|
+
pysentry --all
|
|
201
|
+
|
|
202
|
+
# Filter by severity (only show high and critical)
|
|
203
|
+
pysentry --severity high
|
|
204
|
+
|
|
205
|
+
# Output to JSON file
|
|
206
|
+
pysentry --format json --output audit-results.json
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Advanced Usage
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Using uvx for comprehensive audit
|
|
213
|
+
uvx pysentry-rs --all --format sarif --output security-report.sarif
|
|
214
|
+
|
|
215
|
+
# Check only direct dependencies using OSV database
|
|
216
|
+
uvx pysentry-rs --direct-only --source osv
|
|
217
|
+
|
|
218
|
+
# Or with installed binary
|
|
219
|
+
pysentry --all --format sarif --output security-report.sarif
|
|
220
|
+
pysentry --direct-only --source osv
|
|
221
|
+
|
|
222
|
+
# Ignore specific vulnerabilities
|
|
223
|
+
pysentry --ignore CVE-2023-12345 --ignore GHSA-xxxx-yyyy-zzzz
|
|
224
|
+
|
|
225
|
+
# Disable caching for CI environments
|
|
226
|
+
pysentry --no-cache
|
|
227
|
+
|
|
228
|
+
# Verbose output for debugging
|
|
229
|
+
pysentry --verbose
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Advanced Requirements.txt Usage
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Scan multiple requirements files
|
|
236
|
+
pysentry --requirements requirements.txt --requirements requirements-dev.txt
|
|
237
|
+
|
|
238
|
+
# Check only direct dependencies from requirements.txt
|
|
239
|
+
pysentry --direct-only --resolver uv
|
|
240
|
+
|
|
241
|
+
# Ensure resolver is available in your environment
|
|
242
|
+
source venv/bin/activate # Activate your virtual environment first
|
|
243
|
+
pysentry /path/to/project
|
|
244
|
+
|
|
245
|
+
# Debug requirements.txt resolution
|
|
246
|
+
pysentry --verbose --resolver uv /path/to/project
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Configuration
|
|
250
|
+
|
|
251
|
+
### Command Line Options
|
|
252
|
+
|
|
253
|
+
| Option | Description | Default |
|
|
254
|
+
| ---------------- | ----------------------------------------------------- | ------------------- |
|
|
255
|
+
| `--format` | Output format: `human`, `json`, `sarif` | `human` |
|
|
256
|
+
| `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
|
|
257
|
+
| `--source` | Vulnerability source: `pypa`, `pypi`, `osv` | `pypa` |
|
|
258
|
+
| `--all` | Include all dependencies (main + dev + optional) | `false` |
|
|
259
|
+
| `--direct-only` | Check only direct dependencies | `false` |
|
|
260
|
+
| `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
|
|
261
|
+
| `--output` | Output file path | `stdout` |
|
|
262
|
+
| `--no-cache` | Disable caching | `false` |
|
|
263
|
+
| `--cache-dir` | Custom cache directory | `~/.cache/pysentry` |
|
|
264
|
+
| `--verbose` | Enable verbose output | `false` |
|
|
265
|
+
| `--quiet` | Suppress non-error output | `false` |
|
|
266
|
+
| `--resolver` | Dependency resolver: `auto`, `uv`, `pip-tools` | `auto` |
|
|
267
|
+
| `--requirements` | Additional requirements files (repeatable) | `[]` |
|
|
268
|
+
|
|
269
|
+
### Cache Management
|
|
270
|
+
|
|
271
|
+
PySentry uses an intelligent caching system to avoid redundant API calls:
|
|
272
|
+
|
|
273
|
+
- **Default Location**: `~/.cache/pysentry/` (or system temp directory)
|
|
274
|
+
- **TTL-based Expiration**: Separate expiration for each vulnerability source
|
|
275
|
+
- **Atomic Updates**: Prevents cache corruption during concurrent access
|
|
276
|
+
- **Custom Location**: Use `--cache-dir` to specify alternative location
|
|
277
|
+
|
|
278
|
+
To clear the cache:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
rm -rf ~/.cache/pysentry/
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Supported Project Formats
|
|
285
|
+
|
|
286
|
+
### uv.lock Files (Recommended)
|
|
287
|
+
|
|
288
|
+
PySentry has support for `uv.lock` files:
|
|
289
|
+
|
|
290
|
+
- Exact version resolution
|
|
291
|
+
- Complete dependency graph analysis
|
|
292
|
+
- Source tracking
|
|
293
|
+
- Dependency classification (main, dev, optional) including transitive dependencies
|
|
294
|
+
|
|
295
|
+
### poetry.lock Files
|
|
296
|
+
|
|
297
|
+
Full support for Poetry lock files:
|
|
298
|
+
|
|
299
|
+
- **Exact Version Resolution**: Scans exact dependency versions locked by Poetry
|
|
300
|
+
- **Lock-File Only Analysis**: Relies purely on the lock file structure, no pyproject.toml parsing needed
|
|
301
|
+
- **Complete Dependency Tree**: Analyzes all resolved dependencies including transitive ones
|
|
302
|
+
- **Dependency Classification**: Distinguishes between main dependencies and optional groups (dev, test, etc.)
|
|
303
|
+
- **Source Tracking**: Supports PyPI registry, Git repositories, local paths, and direct URLs
|
|
304
|
+
|
|
305
|
+
**Key Features:**
|
|
306
|
+
|
|
307
|
+
- No external tools required
|
|
308
|
+
- Fast parsing with exact version information
|
|
309
|
+
- Handles Poetry's dependency groups and optional dependencies
|
|
310
|
+
- Perfect for Poetry-managed projects with established lock files
|
|
311
|
+
|
|
312
|
+
### requirements.txt Files (External Resolution)
|
|
313
|
+
|
|
314
|
+
Advanced support for `requirements.txt` files using external dependency resolvers:
|
|
315
|
+
|
|
316
|
+
**Key Features:**
|
|
317
|
+
|
|
318
|
+
- **Dependencies Resolution**: Converts version constraints (e.g., `flask>=2.0,<3.0`) to exact versions using mature external tools
|
|
319
|
+
- **Multiple Resolver Support**:
|
|
320
|
+
- **uv**: Rust-based resolver, extremely fast and reliable (recommended)
|
|
321
|
+
- **pip-tools**: Python-based resolver using `pip-compile`, widely compatible
|
|
322
|
+
- **Auto-detection**: Automatically detects and uses the best available resolver in your environment
|
|
323
|
+
- **Multiple File Support**: Combines `requirements.txt`, `requirements-dev.txt`, `requirements-test.txt`, etc.
|
|
324
|
+
- **Dependency Classification**: Distinguishes between direct and transitive dependencies
|
|
325
|
+
- **Isolated Execution**: Resolvers run in temporary directories to prevent project pollution
|
|
326
|
+
- **Complex Constraint Handling**: Supports version ranges, extras, environment markers, and conflict resolution
|
|
327
|
+
|
|
328
|
+
**Resolution Workflow:**
|
|
329
|
+
|
|
330
|
+
1. Detects `requirements.txt` files in your project
|
|
331
|
+
2. Auto-detects available resolver (`uv` or `pip-tools`) in current environment
|
|
332
|
+
3. Resolves version constraints to exact dependency versions
|
|
333
|
+
4. Scans resolved dependencies for vulnerabilities
|
|
334
|
+
5. Reports findings with direct vs. transitive classification
|
|
335
|
+
|
|
336
|
+
**Environment Setup:**
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Ensure resolver is available in your environment
|
|
340
|
+
source venv/bin/activate # Activate virtual environment
|
|
341
|
+
pip install uv # Install preferred resolver
|
|
342
|
+
pysentry /path/to/project # Run security scan
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### pyproject.toml Files (External Resolution)
|
|
346
|
+
|
|
347
|
+
Support for projects without lock files:
|
|
348
|
+
|
|
349
|
+
- Parses version constraints from `pyproject.toml`
|
|
350
|
+
- **Resolver Required**: Like requirements.txt, needs external resolvers (`uv` or `pip-tools`) to convert version constraints to exact versions for accurate vulnerability scanning
|
|
351
|
+
- Limited dependency graph information compared to lock files
|
|
352
|
+
- Works with both Poetry and PEP 621 formats
|
|
353
|
+
|
|
354
|
+
## Vulnerability Data Sources
|
|
355
|
+
|
|
356
|
+
### PyPA Advisory Database (Default)
|
|
357
|
+
|
|
358
|
+
- Comprehensive coverage of Python ecosystem
|
|
359
|
+
- Community-maintained vulnerability database
|
|
360
|
+
- Regular updates from security researchers
|
|
361
|
+
|
|
362
|
+
### PyPI JSON API
|
|
363
|
+
|
|
364
|
+
- Official PyPI vulnerability data
|
|
365
|
+
- Real-time information
|
|
366
|
+
- Limited to packages hosted on PyPI
|
|
367
|
+
|
|
368
|
+
### OSV.dev
|
|
369
|
+
|
|
370
|
+
- Cross-ecosystem vulnerability database
|
|
371
|
+
- Google-maintained infrastructure
|
|
372
|
+
|
|
373
|
+
## Output Formats
|
|
374
|
+
|
|
375
|
+
### Human-Readable (Default)
|
|
376
|
+
|
|
377
|
+
Most comfortable to read.
|
|
378
|
+
|
|
379
|
+
### JSON
|
|
380
|
+
|
|
381
|
+
```json
|
|
382
|
+
{
|
|
383
|
+
"summary": {
|
|
384
|
+
"total_dependencies": 245,
|
|
385
|
+
"vulnerable_packages": 2,
|
|
386
|
+
"total_vulnerabilities": 3,
|
|
387
|
+
"by_severity": {
|
|
388
|
+
"critical": 1,
|
|
389
|
+
"high": 1,
|
|
390
|
+
"medium": 1,
|
|
391
|
+
"low": 0
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
"vulnerabilities": [...]
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### SARIF (Static Analysis Results Interchange Format)
|
|
399
|
+
|
|
400
|
+
Compatible with GitHub Security tab, VS Code, and other security tools.
|
|
401
|
+
|
|
402
|
+
## Performance
|
|
403
|
+
|
|
404
|
+
PySentry is designed for speed and efficiency:
|
|
405
|
+
|
|
406
|
+
- **Concurrent Processing**: Vulnerability data fetched in parallel
|
|
407
|
+
- **Smart Caching**: Reduces API calls and parsing overhead
|
|
408
|
+
- **Efficient Matching**: In-memory indexing for fast vulnerability lookups
|
|
409
|
+
- **Streaming**: Large databases processed without excessive memory usage
|
|
410
|
+
|
|
411
|
+
### Requirements.txt Resolution Performance
|
|
412
|
+
|
|
413
|
+
PySentry leverages external resolvers for optimal performance:
|
|
414
|
+
|
|
415
|
+
- **uv resolver**: 2-10x faster than pip-tools, handles large dependency trees efficiently
|
|
416
|
+
- **pip-tools resolver**: Reliable fallback, slower but widely compatible
|
|
417
|
+
- **Isolated execution**: Prevents project pollution while maintaining security
|
|
418
|
+
|
|
419
|
+
### Benchmarks
|
|
420
|
+
|
|
421
|
+
Typical performance on a project with 100+ dependencies:
|
|
422
|
+
|
|
423
|
+
- **Cold cache**: 15-30 seconds
|
|
424
|
+
- **Warm cache**: 2-5 seconds
|
|
425
|
+
- **Memory usage**: ~50MB peak
|
|
426
|
+
|
|
427
|
+
## Development
|
|
428
|
+
|
|
429
|
+
### Building from Source
|
|
430
|
+
|
|
431
|
+
```bash
|
|
432
|
+
git clone https://github.com/nyudenkov/pysentry
|
|
433
|
+
cd pysentry
|
|
434
|
+
cargo build --release
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Running Tests
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
cargo test
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Project Structure
|
|
444
|
+
|
|
445
|
+
```
|
|
446
|
+
src/
|
|
447
|
+
├── main.rs # CLI interface
|
|
448
|
+
├── lib.rs # Library API
|
|
449
|
+
├── cache/ # Caching system
|
|
450
|
+
├── dependency/ # Dependency scanning
|
|
451
|
+
├── output/ # Report generation
|
|
452
|
+
├── parsers/ # Project file parsers
|
|
453
|
+
├── providers/ # Vulnerability data sources
|
|
454
|
+
├── types.rs # Core type definitions
|
|
455
|
+
└── vulnerability/ # Vulnerability matching
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Troubleshooting
|
|
459
|
+
|
|
460
|
+
### Common Issues
|
|
461
|
+
|
|
462
|
+
**Error: "No lock file or pyproject.toml found"**
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# Ensure you're in a Python project directory
|
|
466
|
+
ls pyproject.toml uv.lock poetry.lock requirements.txt
|
|
467
|
+
|
|
468
|
+
# Or specify the path explicitly
|
|
469
|
+
pysentry /path/to/python/project
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Error: "No dependency resolver found" or "uv resolver not available"**
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
# Install a supported resolver in your environment
|
|
476
|
+
pip install uv # Recommended - fastest
|
|
477
|
+
pip install pip-tools # Alternative
|
|
478
|
+
|
|
479
|
+
# Verify resolver is available
|
|
480
|
+
uv --version
|
|
481
|
+
pip-compile --version
|
|
482
|
+
|
|
483
|
+
# If using virtual environments, ensure resolver is installed there
|
|
484
|
+
source venv/bin/activate
|
|
485
|
+
pip install uv
|
|
486
|
+
pysentry /path/to/project
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Error: "Failed to resolve requirements"**
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
# Check your requirements.txt syntax
|
|
493
|
+
cat requirements.txt
|
|
494
|
+
|
|
495
|
+
# Try different resolver
|
|
496
|
+
pysentry --resolver pip-tools # if uv fails
|
|
497
|
+
pysentry --resolver uv # if pip-tools fails
|
|
498
|
+
|
|
499
|
+
# Ensure you're in correct environment
|
|
500
|
+
which python
|
|
501
|
+
which uv # or which pip-compile
|
|
502
|
+
|
|
503
|
+
# Debug with verbose output
|
|
504
|
+
pysentry --verbose /path/to/project
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**Error: "Failed to fetch vulnerability data"**
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
# Check network connectivity
|
|
511
|
+
curl -I https://osv-vulnerabilities.storage.googleapis.com/
|
|
512
|
+
|
|
513
|
+
# Try with different source
|
|
514
|
+
pysentry --source pypi
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Slow requirements.txt resolution**
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
# Use faster uv resolver instead of pip-tools
|
|
521
|
+
pysentry --resolver uv
|
|
522
|
+
|
|
523
|
+
# Install uv for better performance (2-10x faster)
|
|
524
|
+
pip install uv
|
|
525
|
+
|
|
526
|
+
# Or use uvx for isolated execution
|
|
527
|
+
uvx pysentry-rs --resolver uv /path/to/project
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Requirements.txt files not being detected**
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
# Ensure requirements.txt exists
|
|
534
|
+
ls requirements.txt
|
|
535
|
+
|
|
536
|
+
# Specify path explicitly
|
|
537
|
+
pysentry /path/to/python/project
|
|
538
|
+
|
|
539
|
+
# Include additional requirements files
|
|
540
|
+
pysentry --requirements requirements-dev.txt --requirements requirements-test.txt
|
|
541
|
+
|
|
542
|
+
# Check if higher-priority files exist (they take precedence)
|
|
543
|
+
ls uv.lock poetry.lock pyproject.toml
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Performance Issues**
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
# Clear cache and retry
|
|
550
|
+
rm -rf ~/.cache/pysentry
|
|
551
|
+
pysentry
|
|
552
|
+
|
|
553
|
+
# Use verbose mode to identify bottlenecks
|
|
554
|
+
pysentry --verbose
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
## Acknowledgments
|
|
558
|
+
|
|
559
|
+
- Inspired by [pip-audit](https://github.com/pypa/pip-audit) and [uv #9189 issue](https://github.com/astral-sh/uv/issues/9189)
|
|
560
|
+
- Originally was a command for [uv](https://github.com/astral-sh/uv)
|
|
561
|
+
- Vulnerability data from [PyPA](https://github.com/pypa/advisory-database), [PyPI](https://pypi.org/), and [OSV.dev](https://osv.dev/)
|
|
562
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pysentry/__init__.py,sha256=kDa2q8nWFR120mhgRaTBxmI8Yxf26tsE5Pdk8tg35VI,5898
|
|
2
|
+
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
+
pysentry/_internal.cpython-310-darwin.so,sha256=kEJNeNbXWheiHjhlP_5WfdCN9B5Q_zDL5i9do_rWsII,6240688
|
|
4
|
+
pysentry_rs-0.2.0.dist-info/METADATA,sha256=JAISzKEXYsg9sS29nTxu1NwyVZVZp1_vCKpxdQ2jLhE,17816
|
|
5
|
+
pysentry_rs-0.2.0.dist-info/WHEEL,sha256=XiGjjeJC2k7oCSYs1QNLi9iFDhofhstbUV6w7vMmp_k,104
|
|
6
|
+
pysentry_rs-0.2.0.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
7
|
+
pysentry_rs-0.2.0.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
8
|
+
pysentry_rs-0.2.0.dist-info/RECORD,,
|
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pysentry-rs
|
|
3
|
-
Version: 0.1.4
|
|
4
|
-
Classifier: Development Status :: 4 - Beta
|
|
5
|
-
Classifier: Intended Audience :: Developers
|
|
6
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
7
|
-
Classifier: Programming Language :: Rust
|
|
8
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
-
Classifier: Topic :: Security
|
|
16
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
Summary: Security vulnerability auditing tool for Python packages
|
|
19
|
-
Author-email: nyudenkov <nyudenkov@pm.me>
|
|
20
|
-
License: GPL-3.0
|
|
21
|
-
Requires-Python: >=3.8
|
|
22
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
23
|
-
Project-URL: Homepage, https://github.com/nyudenkov/pysentry
|
|
24
|
-
Project-URL: Repository, https://github.com/nyudenkov/pysentry
|
|
25
|
-
Project-URL: Issues, https://github.com/nyudenkov/pysentry/issues
|
|
26
|
-
|
|
27
|
-
# 🐍 PySentry
|
|
28
|
-
|
|
29
|
-
A fast, reliable security vulnerability scanner for Python projects, written in Rust.
|
|
30
|
-
|
|
31
|
-
## Overview
|
|
32
|
-
|
|
33
|
-
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `pyproject.toml`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
34
|
-
|
|
35
|
-
## Key Features
|
|
36
|
-
|
|
37
|
-
- **Multiple Project Formats**: Supports both `uv.lock` files (with exact versions) and `pyproject.toml` files
|
|
38
|
-
- **Multiple Data Sources**:
|
|
39
|
-
- PyPA Advisory Database (default)
|
|
40
|
-
- PyPI JSON API
|
|
41
|
-
- OSV.dev (Open Source Vulnerabilities)
|
|
42
|
-
- **Flexible Output**: Human-readable, JSON, and SARIF formats
|
|
43
|
-
- **Performance Focused**:
|
|
44
|
-
- Written in Rust for speed
|
|
45
|
-
- Async/concurrent processing
|
|
46
|
-
- Intelligent caching system
|
|
47
|
-
- **Comprehensive Filtering**:
|
|
48
|
-
- Severity levels (low, medium, high, critical)
|
|
49
|
-
- Dependency types (production, development, optional)
|
|
50
|
-
- Direct vs. transitive dependencies
|
|
51
|
-
- **Enterprise Ready**: SARIF output for IDE/CI integration
|
|
52
|
-
|
|
53
|
-
## Installation
|
|
54
|
-
|
|
55
|
-
Choose the installation method that works best for you:
|
|
56
|
-
|
|
57
|
-
### ⚡ Via uvx (Recommended for occasional use)
|
|
58
|
-
|
|
59
|
-
Run directly without installing (requires [uv](https://docs.astral.sh/uv/)):
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
uvx pysentry-rs /path/to/project
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
This method:
|
|
66
|
-
|
|
67
|
-
- Runs the latest version without installation
|
|
68
|
-
- Automatically manages Python environment
|
|
69
|
-
- Perfect for CI/CD or occasional security audits
|
|
70
|
-
- No need to manage package versions or updates
|
|
71
|
-
|
|
72
|
-
### 📦 From PyPI (Python Package)
|
|
73
|
-
|
|
74
|
-
For Python 3.8+ on Linux and macOS:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
pip install pysentry-rs
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Then use it with Python:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
python -m pysentry /path/to/project
|
|
84
|
-
# or directly if scripts are in PATH
|
|
85
|
-
pysentry-rs /path/to/project
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### ⚡ From Crates.io (Rust Package)
|
|
89
|
-
|
|
90
|
-
If you have Rust installed:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
cargo install pysentry
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### 💾 From GitHub Releases (Pre-built Binaries)
|
|
97
|
-
|
|
98
|
-
Download the latest release for your platform:
|
|
99
|
-
|
|
100
|
-
- **Linux x64**: `pysentry-linux-x64.tar.gz`
|
|
101
|
-
- **Linux x64 (musl)**: `pysentry-linux-x64-musl.tar.gz`
|
|
102
|
-
- **Linux ARM64**: `pysentry-linux-arm64.tar.gz`
|
|
103
|
-
- **macOS x64**: `pysentry-macos-x64.tar.gz`
|
|
104
|
-
- **macOS ARM64**: `pysentry-macos-arm64.tar.gz`
|
|
105
|
-
- **Windows x64**: `pysentry-windows-x64.zip`
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
# Example for Linux x64
|
|
109
|
-
curl -L https://github.com/nyudenkov/pysentry/releases/latest/download/pysentry-linux-x64.tar.gz | tar -xz
|
|
110
|
-
./pysentry-linux-x64/pysentry --help
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### 🔧 From Source
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
git clone https://github.com/nyudenkov/pysentry
|
|
117
|
-
cd pysentry
|
|
118
|
-
cargo build --release
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
The binary will be available at `target/release/pysentry`.
|
|
122
|
-
|
|
123
|
-
### Requirements
|
|
124
|
-
|
|
125
|
-
- **For uvx**: Python 3.8+ and [uv](https://docs.astral.sh/uv/) installed (Linux/macOS only)
|
|
126
|
-
- **For binaries**: No additional dependencies
|
|
127
|
-
- **For Python package**: Python 3.8+ (Linux/macOS only)
|
|
128
|
-
- **For Rust package and source**: Rust 1.79+
|
|
129
|
-
|
|
130
|
-
### Platform Support
|
|
131
|
-
|
|
132
|
-
| Installation Method | Linux | macOS | Windows |
|
|
133
|
-
| ------------------- | ----- | ----- | ------- |
|
|
134
|
-
| uvx | ✅ | ✅ | ❌ |
|
|
135
|
-
| PyPI (pip) | ✅ | ✅ | ❌ |
|
|
136
|
-
| Crates.io (cargo) | ✅ | ✅ | ✅ |
|
|
137
|
-
| GitHub Releases | ✅ | ✅ | ✅ |
|
|
138
|
-
| From Source | ✅ | ✅ | ✅ |
|
|
139
|
-
|
|
140
|
-
**Note**: Windows Python wheels are not available due to compilation complexity. Windows users should use the pre-built binary from GitHub releases, install via cargo and build from source.
|
|
141
|
-
|
|
142
|
-
## Quick Start
|
|
143
|
-
|
|
144
|
-
### Basic Usage
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
# Using uvx (recommended for occasional use)
|
|
148
|
-
uvx pysentry-rs
|
|
149
|
-
uvx pysentry-rs /path/to/python/project
|
|
150
|
-
|
|
151
|
-
# Using installed binary
|
|
152
|
-
pysentry
|
|
153
|
-
pysentry /path/to/python/project
|
|
154
|
-
|
|
155
|
-
# Include development dependencies
|
|
156
|
-
pysentry --dev
|
|
157
|
-
|
|
158
|
-
# Filter by severity (only show high and critical)
|
|
159
|
-
pysentry --severity high
|
|
160
|
-
|
|
161
|
-
# Output to JSON file
|
|
162
|
-
pysentry --format json --output audit-results.json
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Advanced Usage
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
# Using uvx for comprehensive audit
|
|
169
|
-
uvx pysentry-rs --dev --optional --format sarif --output security-report.sarif
|
|
170
|
-
|
|
171
|
-
# Check only direct dependencies using OSV database
|
|
172
|
-
uvx pysentry-rs --direct-only --source osv
|
|
173
|
-
|
|
174
|
-
# Or with installed binary
|
|
175
|
-
pysentry --dev --optional --format sarif --output security-report.sarif
|
|
176
|
-
pysentry --direct-only --source osv
|
|
177
|
-
|
|
178
|
-
# Ignore specific vulnerabilities
|
|
179
|
-
pysentry --ignore CVE-2023-12345 --ignore GHSA-xxxx-yyyy-zzzz
|
|
180
|
-
|
|
181
|
-
# Disable caching for CI environments
|
|
182
|
-
pysentry --no-cache
|
|
183
|
-
|
|
184
|
-
# Verbose output for debugging
|
|
185
|
-
pysentry --verbose
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Configuration
|
|
189
|
-
|
|
190
|
-
### Command Line Options
|
|
191
|
-
|
|
192
|
-
| Option | Description | Default |
|
|
193
|
-
| --------------- | ----------------------------------------------------- | ------------------- |
|
|
194
|
-
| `--format` | Output format: `human`, `json`, `sarif` | `human` |
|
|
195
|
-
| `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
|
|
196
|
-
| `--source` | Vulnerability source: `pypa`, `pypi`, `osv` | `pypa` |
|
|
197
|
-
| `--dev` | Include development dependencies | `false` |
|
|
198
|
-
| `--optional` | Include optional dependencies | `false` |
|
|
199
|
-
| `--direct-only` | Check only direct dependencies | `false` |
|
|
200
|
-
| `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
|
|
201
|
-
| `--output` | Output file path | `stdout` |
|
|
202
|
-
| `--no-cache` | Disable caching | `false` |
|
|
203
|
-
| `--cache-dir` | Custom cache directory | `~/.cache/pysentry` |
|
|
204
|
-
| `--verbose` | Enable verbose output | `false` |
|
|
205
|
-
| `--quiet` | Suppress non-error output | `false` |
|
|
206
|
-
|
|
207
|
-
### Cache Management
|
|
208
|
-
|
|
209
|
-
PySentry uses an intelligent caching system to avoid redundant API calls:
|
|
210
|
-
|
|
211
|
-
- **Default Location**: `~/.cache/pysentry/` (or system temp directory)
|
|
212
|
-
- **TTL-based Expiration**: Separate expiration for each vulnerability source
|
|
213
|
-
- **Atomic Updates**: Prevents cache corruption during concurrent access
|
|
214
|
-
- **Custom Location**: Use `--cache-dir` to specify alternative location
|
|
215
|
-
|
|
216
|
-
To clear the cache:
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
rm -rf ~/.cache/pysentry/
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
## Supported Project Formats
|
|
223
|
-
|
|
224
|
-
### uv.lock Files (Recommended)
|
|
225
|
-
|
|
226
|
-
PySentry has support for `uv.lock` files, providing:
|
|
227
|
-
|
|
228
|
-
- Exact version resolution
|
|
229
|
-
- Complete dependency graph analysis
|
|
230
|
-
- Source tracking
|
|
231
|
-
- Dependency classification (main, dev, optional) including transitioning dependencies
|
|
232
|
-
|
|
233
|
-
### pyproject.toml Files
|
|
234
|
-
|
|
235
|
-
Fallback support for projects without lock files:
|
|
236
|
-
|
|
237
|
-
- Parses version constraints from `pyproject.toml`
|
|
238
|
-
- Limited dependency graph information
|
|
239
|
-
|
|
240
|
-
## Vulnerability Data Sources
|
|
241
|
-
|
|
242
|
-
### PyPA Advisory Database (Default)
|
|
243
|
-
|
|
244
|
-
- Comprehensive coverage of Python ecosystem
|
|
245
|
-
- Community-maintained vulnerability database
|
|
246
|
-
- Regular updates from security researchers
|
|
247
|
-
|
|
248
|
-
### PyPI JSON API
|
|
249
|
-
|
|
250
|
-
- Official PyPI vulnerability data
|
|
251
|
-
- Real-time information
|
|
252
|
-
- Limited to packages hosted on PyPI
|
|
253
|
-
|
|
254
|
-
### OSV.dev
|
|
255
|
-
|
|
256
|
-
- Cross-ecosystem vulnerability database
|
|
257
|
-
- Google-maintained infrastructure
|
|
258
|
-
|
|
259
|
-
## Output Formats
|
|
260
|
-
|
|
261
|
-
### Human-Readable (Default)
|
|
262
|
-
|
|
263
|
-
Most comfortable to read.
|
|
264
|
-
|
|
265
|
-
### JSON
|
|
266
|
-
|
|
267
|
-
```json
|
|
268
|
-
{
|
|
269
|
-
"summary": {
|
|
270
|
-
"total_dependencies": 245,
|
|
271
|
-
"vulnerable_packages": 2,
|
|
272
|
-
"total_vulnerabilities": 3,
|
|
273
|
-
"by_severity": {
|
|
274
|
-
"critical": 1,
|
|
275
|
-
"high": 1,
|
|
276
|
-
"medium": 1,
|
|
277
|
-
"low": 0
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
"vulnerabilities": [...]
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### SARIF (Static Analysis Results Interchange Format)
|
|
285
|
-
|
|
286
|
-
Compatible with GitHub Security tab, VS Code, and other security tools.
|
|
287
|
-
|
|
288
|
-
## Performance
|
|
289
|
-
|
|
290
|
-
PySentry is designed for speed and efficiency:
|
|
291
|
-
|
|
292
|
-
- **Concurrent Processing**: Vulnerability data fetched in parallel
|
|
293
|
-
- **Smart Caching**: Reduces API calls and parsing overhead
|
|
294
|
-
- **Efficient Matching**: In-memory indexing for fast vulnerability lookups
|
|
295
|
-
- **Streaming**: Large databases processed without excessive memory usage
|
|
296
|
-
|
|
297
|
-
### Benchmarks
|
|
298
|
-
|
|
299
|
-
Typical performance on a project with 100+ dependencies:
|
|
300
|
-
|
|
301
|
-
- **Cold cache**: 15-30 seconds
|
|
302
|
-
- **Warm cache**: 2-5 seconds
|
|
303
|
-
- **Memory usage**: ~50MB peak
|
|
304
|
-
|
|
305
|
-
## Development
|
|
306
|
-
|
|
307
|
-
### Building from Source
|
|
308
|
-
|
|
309
|
-
```bash
|
|
310
|
-
git clone https://github.com/nyudenkov/pysentry
|
|
311
|
-
cd pysentry
|
|
312
|
-
cargo build --release
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Running Tests
|
|
316
|
-
|
|
317
|
-
```bash
|
|
318
|
-
cargo test
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### Project Structure
|
|
322
|
-
|
|
323
|
-
```
|
|
324
|
-
src/
|
|
325
|
-
├── main.rs # CLI interface
|
|
326
|
-
├── lib.rs # Library API
|
|
327
|
-
├── cache/ # Caching system
|
|
328
|
-
├── dependency/ # Dependency scanning
|
|
329
|
-
├── output/ # Report generation
|
|
330
|
-
├── parsers/ # Project file parsers
|
|
331
|
-
├── providers/ # Vulnerability data sources
|
|
332
|
-
├── types.rs # Core type definitions
|
|
333
|
-
└── vulnerability/ # Vulnerability matching
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
## Troubleshooting
|
|
337
|
-
|
|
338
|
-
### Common Issues
|
|
339
|
-
|
|
340
|
-
**Error: "No lock file or pyproject.toml found"**
|
|
341
|
-
|
|
342
|
-
```bash
|
|
343
|
-
# Ensure you're in a Python project directory
|
|
344
|
-
ls pyproject.toml uv.lock
|
|
345
|
-
|
|
346
|
-
# Or specify the path explicitly
|
|
347
|
-
pysentry /path/to/python/project
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
**Error: "Failed to fetch vulnerability data"**
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
# Check network connectivity
|
|
354
|
-
curl -I https://osv-vulnerabilities.storage.googleapis.com/
|
|
355
|
-
|
|
356
|
-
# Try with different source
|
|
357
|
-
pysentry --source pypi
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
**Performance Issues**
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
# Clear cache and retry
|
|
364
|
-
rm -rf ~/.cache/pysentry
|
|
365
|
-
pysentry
|
|
366
|
-
|
|
367
|
-
# Use verbose mode to identify bottlenecks
|
|
368
|
-
pysentry --verbose
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
## Acknowledgments
|
|
372
|
-
|
|
373
|
-
- Inspired by [pip-audit](https://github.com/pypa/pip-audit) and [uv #9189 issue](https://github.com/astral-sh/uv/issues/9189)
|
|
374
|
-
- Originally was a command for [uv](https://github.com/astral-sh/uv)
|
|
375
|
-
- Vulnerability data from [PyPA](https://github.com/pypa/advisory-database), [PyPI](https://pypi.org/), and [OSV.dev](https://osv.dev/)
|
|
376
|
-
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pysentry/__init__.py,sha256=TcB6vZ9qN_6fa0HZnuiNiv7VQKwf6jA-kUdWP4ZSwho,5066
|
|
2
|
-
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
-
pysentry/_internal.cpython-310-darwin.so,sha256=0ybE6f2mHFS7DVeljUu3EFx62mSRi6xe-tv8Tj2aJ6g,6137840
|
|
4
|
-
pysentry_rs-0.1.4.dist-info/METADATA,sha256=vl4tTeCjqbM0zh8h-6Z1lfdwVmVfme57xTyeIqrhP20,10992
|
|
5
|
-
pysentry_rs-0.1.4.dist-info/WHEEL,sha256=XiGjjeJC2k7oCSYs1QNLi9iFDhofhstbUV6w7vMmp_k,104
|
|
6
|
-
pysentry_rs-0.1.4.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
7
|
-
pysentry_rs-0.1.4.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
8
|
-
pysentry_rs-0.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|