pysentry-rs 0.3.6__tar.gz → 0.3.7__tar.gz
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_rs-0.3.6 → pysentry_rs-0.3.7}/Cargo.lock +14 -14
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/Cargo.toml +6 -6
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/PKG-INFO +5 -5
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/README.md +4 -4
- pysentry_rs-0.3.7/benchmarks/results/0.3.6.md +141 -0
- pysentry_rs-0.3.7/benchmarks/results/latest.md +141 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/cli.rs +17 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/config.rs +4 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/error.rs +1 -1
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/lib.rs +8 -1
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/output/report.rs +27 -2
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/output/sarif.rs +12 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/mod.rs +3 -0
- pysentry_rs-0.3.7/src/parsers/pylock.rs +771 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/providers/osv.rs +1 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/providers/pypa.rs +47 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/providers/pypi.rs +1 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/vulnerability/database.rs +4 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/vulnerability/matcher.rs +68 -5
- pysentry_rs-0.3.6/benchmarks/results/latest.md +0 -141
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.github/FUNDING.yml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.github/dependabot.yml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.github/workflows/benchmark.yml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.github/workflows/ci.yml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.github/workflows/release.yml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.gitignore +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.pre-commit-config.yaml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/.pre-commit-hooks.yaml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/LICENSE +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/.gitignore +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/.python-version +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/README.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/main.py +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/pyproject.toml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/results/0.2.3.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/results/0.3.1.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/results/0.3.2.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/results/0.3.3.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/results/0.3.4.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/results/0.3.5.md +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/src/benchmark_runner.py +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/src/performance_monitor.py +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/src/report_generator.py +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/src/tool_wrapper.py +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/test_data/large_requirements.txt +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/test_data/small_requirements.txt +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/test_data/uv.lock +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/benchmarks/uv.lock +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/fixtures/pipfile-tests/Pipfile +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/fixtures/pipfile-tests/Pipfile.lock +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/fixtures/pipfile-vulnerable-tests/Pipfile +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/fixtures/requirements-tests/requirements-dev.txt +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/fixtures/requirements-tests/requirements.txt +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/fixtures/requirements-tests-vulnerable/requirements.txt +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/pyproject.toml +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/python/pysentry/__init__.py +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/cache/audit.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/cache/mod.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/cache/storage.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/dependency/mod.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/dependency/resolvers/mod.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/dependency/resolvers/pip_tools.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/dependency/resolvers/uv.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/dependency/scanner.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/main.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/output/mod.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/lock.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/pipfile.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/pipfile_lock.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/poetry_lock.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/pyproject.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/parsers/requirements.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/providers/mod.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/python.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/types.rs +0 -0
- {pysentry_rs-0.3.6 → pysentry_rs-0.3.7}/src/vulnerability/mod.rs +0 -0
|
@@ -1137,7 +1137,7 @@ dependencies = [
|
|
|
1137
1137
|
|
|
1138
1138
|
[[package]]
|
|
1139
1139
|
name = "pysentry"
|
|
1140
|
-
version = "0.3.
|
|
1140
|
+
version = "0.3.7"
|
|
1141
1141
|
dependencies = [
|
|
1142
1142
|
"anyhow",
|
|
1143
1143
|
"async-trait",
|
|
@@ -1277,9 +1277,9 @@ dependencies = [
|
|
|
1277
1277
|
|
|
1278
1278
|
[[package]]
|
|
1279
1279
|
name = "regex"
|
|
1280
|
-
version = "1.11.
|
|
1280
|
+
version = "1.11.2"
|
|
1281
1281
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1282
|
-
checksum = "
|
|
1282
|
+
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
|
|
1283
1283
|
dependencies = [
|
|
1284
1284
|
"aho-corasick",
|
|
1285
1285
|
"memchr",
|
|
@@ -1512,9 +1512,9 @@ dependencies = [
|
|
|
1512
1512
|
|
|
1513
1513
|
[[package]]
|
|
1514
1514
|
name = "serde_json"
|
|
1515
|
-
version = "1.0.
|
|
1515
|
+
version = "1.0.143"
|
|
1516
1516
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1517
|
-
checksum = "
|
|
1517
|
+
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
|
|
1518
1518
|
dependencies = [
|
|
1519
1519
|
"itoa",
|
|
1520
1520
|
"memchr",
|
|
@@ -1686,31 +1686,31 @@ checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
|
|
|
1686
1686
|
|
|
1687
1687
|
[[package]]
|
|
1688
1688
|
name = "tempfile"
|
|
1689
|
-
version = "3.
|
|
1689
|
+
version = "3.21.0"
|
|
1690
1690
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1691
|
-
checksum = "
|
|
1691
|
+
checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
|
|
1692
1692
|
dependencies = [
|
|
1693
1693
|
"fastrand",
|
|
1694
1694
|
"getrandom 0.3.3",
|
|
1695
1695
|
"once_cell",
|
|
1696
1696
|
"rustix",
|
|
1697
|
-
"windows-sys 0.
|
|
1697
|
+
"windows-sys 0.60.2",
|
|
1698
1698
|
]
|
|
1699
1699
|
|
|
1700
1700
|
[[package]]
|
|
1701
1701
|
name = "thiserror"
|
|
1702
|
-
version = "2.0.
|
|
1702
|
+
version = "2.0.16"
|
|
1703
1703
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1704
|
-
checksum = "
|
|
1704
|
+
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
|
|
1705
1705
|
dependencies = [
|
|
1706
1706
|
"thiserror-impl",
|
|
1707
1707
|
]
|
|
1708
1708
|
|
|
1709
1709
|
[[package]]
|
|
1710
1710
|
name = "thiserror-impl"
|
|
1711
|
-
version = "2.0.
|
|
1711
|
+
version = "2.0.16"
|
|
1712
1712
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1713
|
-
checksum = "
|
|
1713
|
+
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
|
|
1714
1714
|
dependencies = [
|
|
1715
1715
|
"proc-macro2",
|
|
1716
1716
|
"quote",
|
|
@@ -2524,9 +2524,9 @@ dependencies = [
|
|
|
2524
2524
|
|
|
2525
2525
|
[[package]]
|
|
2526
2526
|
name = "zip"
|
|
2527
|
-
version = "4.
|
|
2527
|
+
version = "4.5.0"
|
|
2528
2528
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2529
|
-
checksum = "
|
|
2529
|
+
checksum = "8835eb39822904d39cb19465de1159e05d371973f0c6df3a365ad50565ddc8b9"
|
|
2530
2530
|
dependencies = [
|
|
2531
2531
|
"arbitrary",
|
|
2532
2532
|
"crc32fast",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "pysentry"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.7"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
rust-version = "1.79"
|
|
6
6
|
description = "Security vulnerability auditing for Python packages"
|
|
@@ -32,17 +32,17 @@ futures = "0.3.31"
|
|
|
32
32
|
owo-colors = "4.2.2"
|
|
33
33
|
pep440_rs = "0.7.3"
|
|
34
34
|
pyo3 = { version = "0.25.1", features = ["extension-module"], optional = true }
|
|
35
|
-
regex = "1.11.
|
|
35
|
+
regex = "1.11.2"
|
|
36
36
|
reqwest = { version = "0.12.23", features = ["json", "stream", "rustls-tls-native-roots"], default-features = false }
|
|
37
37
|
rustc-hash = "2.1.1"
|
|
38
38
|
serde = { version = "1.0.219", features = ["derive"] }
|
|
39
|
-
serde_json = "1.0.
|
|
39
|
+
serde_json = "1.0.143"
|
|
40
40
|
serde_yaml = "0.9.34"
|
|
41
41
|
sha2 = "0.10.9"
|
|
42
|
-
tempfile = "3.
|
|
43
|
-
thiserror = "2.0.
|
|
42
|
+
tempfile = "3.21.0"
|
|
43
|
+
thiserror = "2.0.16"
|
|
44
44
|
tokio = { version = "1.47.1", features = ["fs", "io-util", "rt-multi-thread", "macros", "process"] }
|
|
45
45
|
toml = "0.9.5"
|
|
46
46
|
tracing = "0.1.41"
|
|
47
47
|
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
|
48
|
-
zip = { version = "4.
|
|
48
|
+
zip = { version = "4.5.0", default-features = false, features = ["deflate"] }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysentry-rs
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -37,11 +37,11 @@ A fast, reliable security vulnerability scanner for Python projects, written in
|
|
|
37
37
|
|
|
38
38
|
## Overview
|
|
39
39
|
|
|
40
|
-
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `Pipfile.lock`, `pyproject.toml`, `Pipfile`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
40
|
+
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `Pipfile.lock`, `pylock.toml`, `pyproject.toml`, `Pipfile`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
41
41
|
|
|
42
42
|
## Key Features
|
|
43
43
|
|
|
44
|
-
- **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `Pipfile.lock`, `pyproject.toml`, `Pipfile`, and `requirements.txt` files
|
|
44
|
+
- **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `Pipfile.lock`, `pylock.toml`, `pyproject.toml`, `Pipfile`, and `requirements.txt` files
|
|
45
45
|
- **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
|
|
46
46
|
- **Multiple Data Sources**:
|
|
47
47
|
- PyPA Advisory Database (default)
|
|
@@ -301,7 +301,7 @@ Add PySentry to your `.pre-commit-config.yaml`:
|
|
|
301
301
|
```yaml
|
|
302
302
|
repos:
|
|
303
303
|
- repo: https://github.com/pysentry/pysentry-pre-commit
|
|
304
|
-
rev: v0.3.
|
|
304
|
+
rev: v0.3.6
|
|
305
305
|
hooks:
|
|
306
306
|
- id: pysentry # default pysentry settings
|
|
307
307
|
```
|
|
@@ -311,7 +311,7 @@ repos:
|
|
|
311
311
|
```yaml
|
|
312
312
|
repos:
|
|
313
313
|
- repo: https://github.com/pysentry/pysentry-pre-commit
|
|
314
|
-
rev: v0.3.
|
|
314
|
+
rev: v0.3.6
|
|
315
315
|
hooks:
|
|
316
316
|
- id: pysentry
|
|
317
317
|
args: ["--sources", "pypa,osv", "--fail-on", "high"]
|
|
@@ -11,11 +11,11 @@ A fast, reliable security vulnerability scanner for Python projects, written in
|
|
|
11
11
|
|
|
12
12
|
## Overview
|
|
13
13
|
|
|
14
|
-
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `Pipfile.lock`, `pyproject.toml`, `Pipfile`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
14
|
+
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `Pipfile.lock`, `pylock.toml`, `pyproject.toml`, `Pipfile`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
15
15
|
|
|
16
16
|
## Key Features
|
|
17
17
|
|
|
18
|
-
- **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `Pipfile.lock`, `pyproject.toml`, `Pipfile`, and `requirements.txt` files
|
|
18
|
+
- **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `Pipfile.lock`, `pylock.toml`, `pyproject.toml`, `Pipfile`, and `requirements.txt` files
|
|
19
19
|
- **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
|
|
20
20
|
- **Multiple Data Sources**:
|
|
21
21
|
- PyPA Advisory Database (default)
|
|
@@ -275,7 +275,7 @@ Add PySentry to your `.pre-commit-config.yaml`:
|
|
|
275
275
|
```yaml
|
|
276
276
|
repos:
|
|
277
277
|
- repo: https://github.com/pysentry/pysentry-pre-commit
|
|
278
|
-
rev: v0.3.
|
|
278
|
+
rev: v0.3.6
|
|
279
279
|
hooks:
|
|
280
280
|
- id: pysentry # default pysentry settings
|
|
281
281
|
```
|
|
@@ -285,7 +285,7 @@ repos:
|
|
|
285
285
|
```yaml
|
|
286
286
|
repos:
|
|
287
287
|
- repo: https://github.com/pysentry/pysentry-pre-commit
|
|
288
|
-
rev: v0.3.
|
|
288
|
+
rev: v0.3.6
|
|
289
289
|
hooks:
|
|
290
290
|
- id: pysentry
|
|
291
291
|
args: ["--sources", "pypa,osv", "--fail-on", "high"]
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# PySentry - pip-audit Benchmark Report
|
|
2
|
+
|
|
3
|
+
**Generated:** 2025-08-21 19:52:35
|
|
4
|
+
**Duration:** 1m 56.44s
|
|
5
|
+
**Total Tests:** 20
|
|
6
|
+
|
|
7
|
+
## Executive Summary
|
|
8
|
+
|
|
9
|
+
**Overall Success Rate:** 100.0% (20/20 successful runs)
|
|
10
|
+
|
|
11
|
+
### Small_Requirements Dataset - Cold Cache
|
|
12
|
+
- **Fastest:** pysentry-pypi (0.250s) - 35.37x faster than slowest
|
|
13
|
+
- **Memory Efficient:** pysentry-osv (11.03 MB) - 9.68x less memory than highest
|
|
14
|
+
|
|
15
|
+
### Small_Requirements Dataset - Hot Cache
|
|
16
|
+
- **Fastest:** pysentry-pypi (0.221s) - 35.46x faster than slowest
|
|
17
|
+
- **Memory Efficient:** pysentry-osv (10.81 MB) - 9.68x less memory than highest
|
|
18
|
+
|
|
19
|
+
### Large_Requirements Dataset - Cold Cache
|
|
20
|
+
- **Fastest:** pysentry-pypi (0.722s) - 27.16x faster than slowest
|
|
21
|
+
- **Memory Efficient:** pysentry-osv (10.93 MB) - 9.84x less memory than highest
|
|
22
|
+
|
|
23
|
+
### Large_Requirements Dataset - Hot Cache
|
|
24
|
+
- **Fastest:** pysentry-pypi (0.686s) - 23.48x faster than slowest
|
|
25
|
+
- **Memory Efficient:** pysentry-osv (11.07 MB) - 9.83x less memory than highest
|
|
26
|
+
|
|
27
|
+
## Test Environment
|
|
28
|
+
|
|
29
|
+
- **Platform:** Linux-6.11.0-1018-azure-x86_64-with-glibc2.39
|
|
30
|
+
- **Python Version:** 3.11.13
|
|
31
|
+
- **CPU Cores:** 4
|
|
32
|
+
- **Total Memory:** 15.62 GB
|
|
33
|
+
- **Available Memory:** 14.63 GB
|
|
34
|
+
|
|
35
|
+
## Performance Comparison
|
|
36
|
+
|
|
37
|
+
### Small_Requirements Dataset - Cold Cache
|
|
38
|
+
|
|
39
|
+
#### Execution Time Comparison
|
|
40
|
+
|
|
41
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
42
|
+
|---------------------|---------------------|---------------------|
|
|
43
|
+
| 🥇 pysentry-pypi | 0.250s | 1.00x |
|
|
44
|
+
| 🥈 pysentry-osv | 1.045s | 4.18x |
|
|
45
|
+
| pysentry-all-sources | 1.152s | 4.60x |
|
|
46
|
+
| pysentry-pypa | 1.155s | 4.61x |
|
|
47
|
+
| pip-audit-default | 8.852s | 35.37x |
|
|
48
|
+
|
|
49
|
+
#### Memory Usage Comparison
|
|
50
|
+
|
|
51
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
52
|
+
|---------------------|---------------------|---------------------|
|
|
53
|
+
| 🥇 pysentry-osv | 11.03 MB | 1.00x |
|
|
54
|
+
| 🥈 pysentry-pypi | 11.64 MB | 1.06x |
|
|
55
|
+
| pip-audit-default | 45.64 MB | 4.14x |
|
|
56
|
+
| pysentry-pypa | 75.38 MB | 6.84x |
|
|
57
|
+
| pysentry-all-sources | 106.78 MB | 9.68x |
|
|
58
|
+
|
|
59
|
+
### Small_Requirements Dataset - Hot Cache
|
|
60
|
+
|
|
61
|
+
#### Execution Time Comparison
|
|
62
|
+
|
|
63
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
64
|
+
|---------------------|---------------------|---------------------|
|
|
65
|
+
| 🥇 pysentry-pypi | 0.221s | 1.00x |
|
|
66
|
+
| 🥈 pysentry-pypa | 0.729s | 3.29x |
|
|
67
|
+
| pysentry-osv | 0.982s | 4.43x |
|
|
68
|
+
| pysentry-all-sources | 1.112s | 5.02x |
|
|
69
|
+
| pip-audit-default | 7.854s | 35.46x |
|
|
70
|
+
|
|
71
|
+
#### Memory Usage Comparison
|
|
72
|
+
|
|
73
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
74
|
+
|---------------------|---------------------|---------------------|
|
|
75
|
+
| 🥇 pysentry-osv | 10.81 MB | 1.00x |
|
|
76
|
+
| 🥈 pysentry-pypi | 11.93 MB | 1.10x |
|
|
77
|
+
| pip-audit-default | 44.88 MB | 4.15x |
|
|
78
|
+
| pysentry-pypa | 69.38 MB | 6.42x |
|
|
79
|
+
| pysentry-all-sources | 104.60 MB | 9.68x |
|
|
80
|
+
|
|
81
|
+
### Large_Requirements Dataset - Cold Cache
|
|
82
|
+
|
|
83
|
+
#### Execution Time Comparison
|
|
84
|
+
|
|
85
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
86
|
+
|---------------------|---------------------|---------------------|
|
|
87
|
+
| 🥇 pysentry-pypi | 0.722s | 1.00x |
|
|
88
|
+
| 🥈 pysentry-pypa | 1.258s | 1.74x |
|
|
89
|
+
| pysentry-all-sources | 3.183s | 4.41x |
|
|
90
|
+
| pysentry-osv | 3.714s | 5.14x |
|
|
91
|
+
| pip-audit-default | 19.619s | 27.16x |
|
|
92
|
+
|
|
93
|
+
#### Memory Usage Comparison
|
|
94
|
+
|
|
95
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
96
|
+
|---------------------|---------------------|---------------------|
|
|
97
|
+
| 🥇 pysentry-osv | 10.93 MB | 1.00x |
|
|
98
|
+
| 🥈 pysentry-pypi | 14.27 MB | 1.31x |
|
|
99
|
+
| pip-audit-default | 47.34 MB | 4.33x |
|
|
100
|
+
| pysentry-pypa | 74.92 MB | 6.85x |
|
|
101
|
+
| pysentry-all-sources | 107.52 MB | 9.84x |
|
|
102
|
+
|
|
103
|
+
### Large_Requirements Dataset - Hot Cache
|
|
104
|
+
|
|
105
|
+
#### Execution Time Comparison
|
|
106
|
+
|
|
107
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
108
|
+
|---------------------|---------------------|---------------------|
|
|
109
|
+
| 🥇 pysentry-pypi | 0.686s | 1.00x |
|
|
110
|
+
| 🥈 pysentry-pypa | 1.206s | 1.76x |
|
|
111
|
+
| pysentry-all-sources | 3.464s | 5.05x |
|
|
112
|
+
| pysentry-osv | 3.799s | 5.54x |
|
|
113
|
+
| pip-audit-default | 16.105s | 23.48x |
|
|
114
|
+
|
|
115
|
+
#### Memory Usage Comparison
|
|
116
|
+
|
|
117
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
118
|
+
|---------------------|---------------------|---------------------|
|
|
119
|
+
| 🥇 pysentry-osv | 11.07 MB | 1.00x |
|
|
120
|
+
| 🥈 pysentry-pypi | 11.27 MB | 1.02x |
|
|
121
|
+
| pip-audit-default | 47.18 MB | 4.26x |
|
|
122
|
+
| pysentry-pypa | 52.84 MB | 4.77x |
|
|
123
|
+
| pysentry-all-sources | 108.84 MB | 9.83x |
|
|
124
|
+
|
|
125
|
+
## Detailed Analysis
|
|
126
|
+
|
|
127
|
+
### Pysentry Performance
|
|
128
|
+
|
|
129
|
+
- **Execution Time:** Avg: 1.542s, Min: 0.221s, Max: 3.799s
|
|
130
|
+
|
|
131
|
+
- **Memory Usage:** Avg: 49.58 MB, Min: 10.81 MB, Max: 108.84 MB
|
|
132
|
+
|
|
133
|
+
- **Success Rate:** 100.0% (16/16)
|
|
134
|
+
|
|
135
|
+
### Pip-Audit Performance
|
|
136
|
+
|
|
137
|
+
- **Execution Time:** Avg: 13.108s, Min: 7.854s, Max: 19.619s
|
|
138
|
+
|
|
139
|
+
- **Memory Usage:** Avg: 46.26 MB, Min: 44.88 MB, Max: 47.34 MB
|
|
140
|
+
|
|
141
|
+
- **Success Rate:** 100.0% (4/4)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# PySentry - pip-audit Benchmark Report
|
|
2
|
+
|
|
3
|
+
**Generated:** 2025-08-21 19:52:35
|
|
4
|
+
**Duration:** 1m 56.44s
|
|
5
|
+
**Total Tests:** 20
|
|
6
|
+
|
|
7
|
+
## Executive Summary
|
|
8
|
+
|
|
9
|
+
**Overall Success Rate:** 100.0% (20/20 successful runs)
|
|
10
|
+
|
|
11
|
+
### Small_Requirements Dataset - Cold Cache
|
|
12
|
+
- **Fastest:** pysentry-pypi (0.250s) - 35.37x faster than slowest
|
|
13
|
+
- **Memory Efficient:** pysentry-osv (11.03 MB) - 9.68x less memory than highest
|
|
14
|
+
|
|
15
|
+
### Small_Requirements Dataset - Hot Cache
|
|
16
|
+
- **Fastest:** pysentry-pypi (0.221s) - 35.46x faster than slowest
|
|
17
|
+
- **Memory Efficient:** pysentry-osv (10.81 MB) - 9.68x less memory than highest
|
|
18
|
+
|
|
19
|
+
### Large_Requirements Dataset - Cold Cache
|
|
20
|
+
- **Fastest:** pysentry-pypi (0.722s) - 27.16x faster than slowest
|
|
21
|
+
- **Memory Efficient:** pysentry-osv (10.93 MB) - 9.84x less memory than highest
|
|
22
|
+
|
|
23
|
+
### Large_Requirements Dataset - Hot Cache
|
|
24
|
+
- **Fastest:** pysentry-pypi (0.686s) - 23.48x faster than slowest
|
|
25
|
+
- **Memory Efficient:** pysentry-osv (11.07 MB) - 9.83x less memory than highest
|
|
26
|
+
|
|
27
|
+
## Test Environment
|
|
28
|
+
|
|
29
|
+
- **Platform:** Linux-6.11.0-1018-azure-x86_64-with-glibc2.39
|
|
30
|
+
- **Python Version:** 3.11.13
|
|
31
|
+
- **CPU Cores:** 4
|
|
32
|
+
- **Total Memory:** 15.62 GB
|
|
33
|
+
- **Available Memory:** 14.63 GB
|
|
34
|
+
|
|
35
|
+
## Performance Comparison
|
|
36
|
+
|
|
37
|
+
### Small_Requirements Dataset - Cold Cache
|
|
38
|
+
|
|
39
|
+
#### Execution Time Comparison
|
|
40
|
+
|
|
41
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
42
|
+
|---------------------|---------------------|---------------------|
|
|
43
|
+
| 🥇 pysentry-pypi | 0.250s | 1.00x |
|
|
44
|
+
| 🥈 pysentry-osv | 1.045s | 4.18x |
|
|
45
|
+
| pysentry-all-sources | 1.152s | 4.60x |
|
|
46
|
+
| pysentry-pypa | 1.155s | 4.61x |
|
|
47
|
+
| pip-audit-default | 8.852s | 35.37x |
|
|
48
|
+
|
|
49
|
+
#### Memory Usage Comparison
|
|
50
|
+
|
|
51
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
52
|
+
|---------------------|---------------------|---------------------|
|
|
53
|
+
| 🥇 pysentry-osv | 11.03 MB | 1.00x |
|
|
54
|
+
| 🥈 pysentry-pypi | 11.64 MB | 1.06x |
|
|
55
|
+
| pip-audit-default | 45.64 MB | 4.14x |
|
|
56
|
+
| pysentry-pypa | 75.38 MB | 6.84x |
|
|
57
|
+
| pysentry-all-sources | 106.78 MB | 9.68x |
|
|
58
|
+
|
|
59
|
+
### Small_Requirements Dataset - Hot Cache
|
|
60
|
+
|
|
61
|
+
#### Execution Time Comparison
|
|
62
|
+
|
|
63
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
64
|
+
|---------------------|---------------------|---------------------|
|
|
65
|
+
| 🥇 pysentry-pypi | 0.221s | 1.00x |
|
|
66
|
+
| 🥈 pysentry-pypa | 0.729s | 3.29x |
|
|
67
|
+
| pysentry-osv | 0.982s | 4.43x |
|
|
68
|
+
| pysentry-all-sources | 1.112s | 5.02x |
|
|
69
|
+
| pip-audit-default | 7.854s | 35.46x |
|
|
70
|
+
|
|
71
|
+
#### Memory Usage Comparison
|
|
72
|
+
|
|
73
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
74
|
+
|---------------------|---------------------|---------------------|
|
|
75
|
+
| 🥇 pysentry-osv | 10.81 MB | 1.00x |
|
|
76
|
+
| 🥈 pysentry-pypi | 11.93 MB | 1.10x |
|
|
77
|
+
| pip-audit-default | 44.88 MB | 4.15x |
|
|
78
|
+
| pysentry-pypa | 69.38 MB | 6.42x |
|
|
79
|
+
| pysentry-all-sources | 104.60 MB | 9.68x |
|
|
80
|
+
|
|
81
|
+
### Large_Requirements Dataset - Cold Cache
|
|
82
|
+
|
|
83
|
+
#### Execution Time Comparison
|
|
84
|
+
|
|
85
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
86
|
+
|---------------------|---------------------|---------------------|
|
|
87
|
+
| 🥇 pysentry-pypi | 0.722s | 1.00x |
|
|
88
|
+
| 🥈 pysentry-pypa | 1.258s | 1.74x |
|
|
89
|
+
| pysentry-all-sources | 3.183s | 4.41x |
|
|
90
|
+
| pysentry-osv | 3.714s | 5.14x |
|
|
91
|
+
| pip-audit-default | 19.619s | 27.16x |
|
|
92
|
+
|
|
93
|
+
#### Memory Usage Comparison
|
|
94
|
+
|
|
95
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
96
|
+
|---------------------|---------------------|---------------------|
|
|
97
|
+
| 🥇 pysentry-osv | 10.93 MB | 1.00x |
|
|
98
|
+
| 🥈 pysentry-pypi | 14.27 MB | 1.31x |
|
|
99
|
+
| pip-audit-default | 47.34 MB | 4.33x |
|
|
100
|
+
| pysentry-pypa | 74.92 MB | 6.85x |
|
|
101
|
+
| pysentry-all-sources | 107.52 MB | 9.84x |
|
|
102
|
+
|
|
103
|
+
### Large_Requirements Dataset - Hot Cache
|
|
104
|
+
|
|
105
|
+
#### Execution Time Comparison
|
|
106
|
+
|
|
107
|
+
| Tool Configuration | Execution Time | Relative Performance |
|
|
108
|
+
|---------------------|---------------------|---------------------|
|
|
109
|
+
| 🥇 pysentry-pypi | 0.686s | 1.00x |
|
|
110
|
+
| 🥈 pysentry-pypa | 1.206s | 1.76x |
|
|
111
|
+
| pysentry-all-sources | 3.464s | 5.05x |
|
|
112
|
+
| pysentry-osv | 3.799s | 5.54x |
|
|
113
|
+
| pip-audit-default | 16.105s | 23.48x |
|
|
114
|
+
|
|
115
|
+
#### Memory Usage Comparison
|
|
116
|
+
|
|
117
|
+
| Tool Configuration | Peak Memory | Relative Performance |
|
|
118
|
+
|---------------------|---------------------|---------------------|
|
|
119
|
+
| 🥇 pysentry-osv | 11.07 MB | 1.00x |
|
|
120
|
+
| 🥈 pysentry-pypi | 11.27 MB | 1.02x |
|
|
121
|
+
| pip-audit-default | 47.18 MB | 4.26x |
|
|
122
|
+
| pysentry-pypa | 52.84 MB | 4.77x |
|
|
123
|
+
| pysentry-all-sources | 108.84 MB | 9.83x |
|
|
124
|
+
|
|
125
|
+
## Detailed Analysis
|
|
126
|
+
|
|
127
|
+
### Pysentry Performance
|
|
128
|
+
|
|
129
|
+
- **Execution Time:** Avg: 1.542s, Min: 0.221s, Max: 3.799s
|
|
130
|
+
|
|
131
|
+
- **Memory Usage:** Avg: 49.58 MB, Min: 10.81 MB, Max: 108.84 MB
|
|
132
|
+
|
|
133
|
+
- **Success Rate:** 100.0% (16/16)
|
|
134
|
+
|
|
135
|
+
### Pip-Audit Performance
|
|
136
|
+
|
|
137
|
+
- **Execution Time:** Avg: 13.108s, Min: 7.854s, Max: 19.619s
|
|
138
|
+
|
|
139
|
+
- **Memory Usage:** Avg: 46.26 MB, Min: 44.88 MB, Max: 47.34 MB
|
|
140
|
+
|
|
141
|
+
- **Success Rate:** 100.0% (4/4)
|
|
@@ -151,6 +151,10 @@ pub struct AuditArgs {
|
|
|
151
151
|
#[arg(long)]
|
|
152
152
|
pub direct_only: bool,
|
|
153
153
|
|
|
154
|
+
/// Include withdrawn vulnerabilities in results
|
|
155
|
+
#[arg(long)]
|
|
156
|
+
pub include_withdrawn: bool,
|
|
157
|
+
|
|
154
158
|
/// Disable caching
|
|
155
159
|
#[arg(long)]
|
|
156
160
|
pub no_cache: bool,
|
|
@@ -363,6 +367,10 @@ impl AuditArgs {
|
|
|
363
367
|
merged.detailed = config.defaults.detailed;
|
|
364
368
|
}
|
|
365
369
|
|
|
370
|
+
if !self.include_withdrawn {
|
|
371
|
+
merged.include_withdrawn = config.defaults.include_withdrawn;
|
|
372
|
+
}
|
|
373
|
+
|
|
366
374
|
if self.resolver == ResolverTypeArg::Uv && config.resolver.resolver_type != "uv" {
|
|
367
375
|
merged.resolver = match config.resolver.resolver_type.as_str() {
|
|
368
376
|
"pip-tools" => ResolverTypeArg::PipTools,
|
|
@@ -1010,6 +1018,7 @@ async fn perform_audit(audit_args: &AuditArgs, cache_dir: &Path) -> Result<Audit
|
|
|
1010
1018
|
audit_args.severity.clone().into(),
|
|
1011
1019
|
audit_args.ignore_ids.to_vec(),
|
|
1012
1020
|
audit_args.direct_only,
|
|
1021
|
+
audit_args.include_withdrawn,
|
|
1013
1022
|
);
|
|
1014
1023
|
let matcher = VulnerabilityMatcher::new(database, matcher_config);
|
|
1015
1024
|
|
|
@@ -1117,6 +1126,7 @@ pub async fn config_init(args: &ConfigInitArgs) -> Result<()> {
|
|
|
1117
1126
|
println!("- Severity: low, medium, high, critical");
|
|
1118
1127
|
println!("- Sources: pypa, pypi, osv");
|
|
1119
1128
|
println!("- Resolver: uv, pip-tools");
|
|
1129
|
+
println!("- Include withdrawn: true/false");
|
|
1120
1130
|
|
|
1121
1131
|
Ok(())
|
|
1122
1132
|
}
|
|
@@ -1192,6 +1202,10 @@ pub async fn config_show(args: &ConfigShowArgs) -> Result<()> {
|
|
|
1192
1202
|
config_loader.config.defaults.direct_only
|
|
1193
1203
|
);
|
|
1194
1204
|
println!(" Detailed: {}", config_loader.config.defaults.detailed);
|
|
1205
|
+
println!(
|
|
1206
|
+
" Include withdrawn: {}",
|
|
1207
|
+
config_loader.config.defaults.include_withdrawn
|
|
1208
|
+
);
|
|
1195
1209
|
println!();
|
|
1196
1210
|
println!(
|
|
1197
1211
|
" Sources: {}",
|
|
@@ -1292,6 +1306,9 @@ fail_on = "high"
|
|
|
1292
1306
|
# Uncomment to include dev/optional dependencies
|
|
1293
1307
|
# scope = "all"
|
|
1294
1308
|
|
|
1309
|
+
# Uncomment to include withdrawn vulnerabilities by default
|
|
1310
|
+
# include_withdrawn = true
|
|
1311
|
+
|
|
1295
1312
|
[sources]
|
|
1296
1313
|
# Choose your vulnerability sources
|
|
1297
1314
|
enabled = ["pypa"]
|
|
@@ -75,6 +75,9 @@ pub struct DefaultConfig {
|
|
|
75
75
|
|
|
76
76
|
#[serde(default)]
|
|
77
77
|
pub detailed: bool,
|
|
78
|
+
|
|
79
|
+
#[serde(default)]
|
|
80
|
+
pub include_withdrawn: bool,
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
@@ -481,6 +484,7 @@ impl Default for DefaultConfig {
|
|
|
481
484
|
scope: default_scope(),
|
|
482
485
|
direct_only: false,
|
|
483
486
|
detailed: false,
|
|
487
|
+
include_withdrawn: false,
|
|
484
488
|
}
|
|
485
489
|
}
|
|
486
490
|
}
|
|
@@ -24,7 +24,7 @@ pub type Result<T> = std::result::Result<T, AuditError>;
|
|
|
24
24
|
/// Audit error types
|
|
25
25
|
#[derive(Debug, Error)]
|
|
26
26
|
pub enum AuditError {
|
|
27
|
-
#[error("No dependency information found.
|
|
27
|
+
#[error("No dependency information found. Generate a lock file (uv.lock, poetry.lock, Pipfile.lock, pylock.toml) or add pyproject.toml/requirements.txt")]
|
|
28
28
|
NoDependencyInfo,
|
|
29
29
|
|
|
30
30
|
#[error("Failed to download vulnerability database: {0}")]
|
|
@@ -97,6 +97,8 @@ impl AuditEngine {
|
|
|
97
97
|
source_type: VulnerabilitySourceType,
|
|
98
98
|
min_severity: SeverityLevel,
|
|
99
99
|
ignore_ids: &[String],
|
|
100
|
+
direct_only: bool,
|
|
101
|
+
include_withdrawn: bool,
|
|
100
102
|
) -> Result<AuditReport> {
|
|
101
103
|
let project_path = project_path.as_ref();
|
|
102
104
|
|
|
@@ -125,7 +127,12 @@ impl AuditEngine {
|
|
|
125
127
|
let database = vuln_source.fetch_vulnerabilities(&packages).await?;
|
|
126
128
|
|
|
127
129
|
// 4. Match vulnerabilities
|
|
128
|
-
let matcher_config = MatcherConfig::new(
|
|
130
|
+
let matcher_config = MatcherConfig::new(
|
|
131
|
+
min_severity,
|
|
132
|
+
ignore_ids.to_vec(),
|
|
133
|
+
direct_only,
|
|
134
|
+
include_withdrawn,
|
|
135
|
+
);
|
|
129
136
|
let matcher = VulnerabilityMatcher::new(database, matcher_config);
|
|
130
137
|
|
|
131
138
|
let matches = matcher.find_vulnerabilities(&dependencies)?;
|
|
@@ -263,11 +263,18 @@ impl ReportGenerator {
|
|
|
263
263
|
String::new()
|
|
264
264
|
};
|
|
265
265
|
|
|
266
|
+
let withdrawn_tag = if m.vulnerability.withdrawn.is_some() {
|
|
267
|
+
format!(" {}", "(WITHDRAWN)".yellow().bold())
|
|
268
|
+
} else {
|
|
269
|
+
String::new()
|
|
270
|
+
};
|
|
271
|
+
|
|
266
272
|
writeln!(
|
|
267
273
|
output,
|
|
268
|
-
" {}. {} {} v{} [{}]{}",
|
|
274
|
+
" {}. {}{} {} v{} [{}]{}",
|
|
269
275
|
i + 1,
|
|
270
276
|
ColoredOutput::vulnerability_id(&m.vulnerability.id),
|
|
277
|
+
withdrawn_tag,
|
|
271
278
|
ColoredOutput::package_name(&m.package_name.to_string()),
|
|
272
279
|
m.installed_version,
|
|
273
280
|
ColoredOutput::severity(&m.vulnerability.severity),
|
|
@@ -438,12 +445,19 @@ impl ReportGenerator {
|
|
|
438
445
|
String::new()
|
|
439
446
|
};
|
|
440
447
|
|
|
448
|
+
let withdrawn_tag = if m.vulnerability.withdrawn.is_some() {
|
|
449
|
+
" ⚠️ **WITHDRAWN**"
|
|
450
|
+
} else {
|
|
451
|
+
""
|
|
452
|
+
};
|
|
453
|
+
|
|
441
454
|
writeln!(
|
|
442
455
|
output,
|
|
443
|
-
"### {}. {} `{}`{}",
|
|
456
|
+
"### {}. {} `{}`{}{}",
|
|
444
457
|
i + 1,
|
|
445
458
|
severity_icon,
|
|
446
459
|
m.vulnerability.id,
|
|
460
|
+
withdrawn_tag,
|
|
447
461
|
source_tag
|
|
448
462
|
)?;
|
|
449
463
|
writeln!(output)?;
|
|
@@ -459,6 +473,14 @@ impl ReportGenerator {
|
|
|
459
473
|
writeln!(output, "- **CVSS Score:** {cvss:.1}")?;
|
|
460
474
|
}
|
|
461
475
|
|
|
476
|
+
if let Some(withdrawn_date) = &m.vulnerability.withdrawn {
|
|
477
|
+
writeln!(
|
|
478
|
+
output,
|
|
479
|
+
"- **⚠️ Withdrawn:** {}",
|
|
480
|
+
withdrawn_date.format("%Y-%m-%d")
|
|
481
|
+
)?;
|
|
482
|
+
}
|
|
483
|
+
|
|
462
484
|
writeln!(output, "- **Summary:** {}", m.vulnerability.summary)?;
|
|
463
485
|
|
|
464
486
|
if let Some(description) = &m.vulnerability.description {
|
|
@@ -546,6 +568,7 @@ impl ReportGenerator {
|
|
|
546
568
|
references: m.vulnerability.references.clone(),
|
|
547
569
|
is_direct: m.is_direct,
|
|
548
570
|
source: m.vulnerability.source.clone(),
|
|
571
|
+
withdrawn: m.vulnerability.withdrawn.map(|dt| dt.to_rfc3339()),
|
|
549
572
|
})
|
|
550
573
|
.collect(),
|
|
551
574
|
fix_suggestions: report
|
|
@@ -610,6 +633,7 @@ struct JsonVulnerability {
|
|
|
610
633
|
references: Vec<String>,
|
|
611
634
|
is_direct: bool,
|
|
612
635
|
source: Option<String>,
|
|
636
|
+
withdrawn: Option<String>,
|
|
613
637
|
}
|
|
614
638
|
|
|
615
639
|
#[derive(Serialize, Deserialize)]
|
|
@@ -660,6 +684,7 @@ mod tests {
|
|
|
660
684
|
published: None,
|
|
661
685
|
modified: None,
|
|
662
686
|
source: Some("test".to_string()),
|
|
687
|
+
withdrawn: None,
|
|
663
688
|
};
|
|
664
689
|
|
|
665
690
|
let matches = vec![VulnerabilityMatch {
|
|
@@ -326,6 +326,17 @@ impl SarifGenerator {
|
|
|
326
326
|
rule["properties"]["cvss_score"] = json!(cvss);
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
// Add withdrawal information if available
|
|
330
|
+
if let Some(withdrawn_date) = &m.vulnerability.withdrawn {
|
|
331
|
+
rule["properties"]["withdrawn"] = json!(withdrawn_date.to_rfc3339());
|
|
332
|
+
rule["properties"]["tags"] = json!([
|
|
333
|
+
"security",
|
|
334
|
+
"vulnerability",
|
|
335
|
+
format!("{:?}", m.vulnerability.severity).to_lowercase(),
|
|
336
|
+
"withdrawn"
|
|
337
|
+
]);
|
|
338
|
+
}
|
|
339
|
+
|
|
329
340
|
// Add timestamps if available
|
|
330
341
|
if let Some(published) = &m.vulnerability.published {
|
|
331
342
|
rule["properties"]["published_date"] = json!(published.to_string());
|
|
@@ -643,6 +654,7 @@ mod tests {
|
|
|
643
654
|
published: None,
|
|
644
655
|
modified: None,
|
|
645
656
|
source: Some("test".to_string()),
|
|
657
|
+
withdrawn: None,
|
|
646
658
|
}
|
|
647
659
|
}
|
|
648
660
|
|