DepReach
DepReach is a Python Software Composition Analysis (SCA) tool. It identifies vulnerable package versions, maps fix patches to functions and supported literal data in the versioned dependency source, and reports possible static call paths from your application.
A reachable patch-associated function is evidence for triage, not proof of exploitability. Missing source, unmatched patches, and unsupported dynamic behavior remain unknown, rather than being labeled safe. See analysis contract and limitations.
Features
- SBOM — CycloneDX via cyclonedx-py for Python; an additional npm lockfile command preserves installation instances
- npm SCA preview —
python -m scripts.npm_inventory --input APP --output NEW_REPORT_DIR --scan; scope and commands.--sourcesverifies package bytes;--syntaxextracts JS/TS AST facts (node extra). JS/TS reachability is not implemented yet - Vulnerability lookup — Local VDB (e.g. appthreat-vulnerability-db)
- Reachability — Qualified Python symbols, scoped imports and re-exports, simple instances and inheritance, exact old-side patch context, and call-chain evidence
- Caching — SQLite cache keyed by project and dependency source contents, patch contents, analysis options and analyzer version
- HTML report — Interactive dependency graph, filter by package, zoom, “hide clean”
- SARIF — Output for ASPM / Code Scanning with reachability in
result.properties
Installation
DepReach is available on PyPI. Requires Python 3.10+:
pip install depreach
Or install from source:
git clone https://github.com/akiracrying/DepReach.git && cd DepReach
pip install .
Quick start
depreach -i /path/to/your/project -o report.json
Reports are written to reports/<project_name>/ (JSON, SBOM, HTML). Use --sarif <file> to also emit SARIF 2.1 with call paths.
For inventory generation, provide a resolved virtualenv, poetry.lock, Pipfile/Pipfile.lock, or pinned requirements.txt. A bare pyproject.toml or uv.lock is not supported yet. A requirements-only inventory may omit transitive dependencies; use the resolved environment when complete inventory matters. The scanner rejects missing package identities and unversioned inventory entries. VDB must contain both a populated index and vulnerability data; an incomplete database is a scan error.
The vulnerable package's exact PyPI source distribution is downloaded and checked against its registry SHA256. Sources for declared intermediate dependencies are prepared automatically; missing transitive versions remain explicit blockers. Additional source roots can also be supplied explicitly. No source package build/install hook runs during reachability analysis. Inventorying an existing virtualenv can invoke that environment's interpreter through cyclonedx-py; use environments you trust.
Usage
depreach -i <input_dir> -o report.json [options]
| Option | Description |
|---|---|
-i, --input |
Source code directory (required) |
-o, --output |
Report filename; output dir is reports/<project_name>/ |
--skip-update |
Skip updating the vulnerability database |
--cache |
Cache reachability results in SQLite |
-j, --jobs |
Parallel jobs for reachability (default: 6) |
--ignore |
Comma-separated package names to ignore (e.g. flask,requests) |
--sarif |
Write SARIF 2.1 with status, limitations and call flows |
--dependency-source |
Additional dependency source root; repeat for intermediary libraries |
--package-source |
pkg:pypi/name@version=path: use explicitly supplied source for a package version |
--include-tests |
Include first-party tests in analysis roots (excluded by default) |
--target-environment |
JSON marker environment overrides for pinned requirements; defaults to scanner environment |
--requirements |
Explicit requirements file, relative to the input directory or absolute |
--all-environments |
Retain marker alternatives; conflicting versions cannot form one resolved runtime |
Scan exit codes: 0 = no known vulnerabilities in the supplied inventory; 1 = vulnerabilities, with no modeled path found for every finding; 2 = at least one reachable patch-associated function; 3 = inconclusive analysis with no reachable finding; 4 = scan/export failure. Argument syntax errors use argparse's standard exit code 2.
1 is not a safety verdict. JSON uses status and a nullable is_reachable; unknown and unsupported are never exported as false. CLI, HTML and SARIF share the same semantics. This changes the previous JSON reachability shape; old cache records are ignored.
Example
depreach -i ./my-app -o report.json --cache --ignore "flask" --sarif report.sarif
Output
| Artifact | Path | Description |
|---|---|---|
| JSON report | reports/<name>/report.json |
Vulns with CVE, severity, description, references, reachability |
| SBOM | reports/<name>/<name>_sbom.json |
CycloneDX SBOM |
| HTML report | reports/<name>/report.html |
Interactive graph, filter by package, zoom |
| SARIF | path from --sarif |
SARIF 2.1 with isReachable in result properties (for ASPM) |
Use as a library
from depreach import run
vulns, exit_code = run(
input_dir="./my-app",
output_file="report.json",
skip_update=False,
cache=True,
jobs=6,
ignore="flask,requests",
sarif_path="report.sarif",
)
# exit_code: 0 = no CVEs, 1 = no modeled path, 2 = reachable, 3 = inconclusive
Reviewed vulnerability models remain separate from patch candidates. JSON includes mapping evidence levels, unsupported change kinds and explicit source blockers. See the labeled evaluation corpus for measured coverage and known abstentions; these measurements do not establish ecosystem accuracy.
Remaining work and acceptance criteria: next implementation steps.
Verification
pip install -e ".[dev,node]"
python -m pytest tests -q
python -m scripts.benchmark_python --clone
Unit and regression tests run without external network access or a populated VDB. The optional benchmark downloads pinned Requests/Werkzeug sources and real fix diffs, analyzes eight small caller programs, and writes evidence to reports/python-benchmark/. It never executes the target programs. These probes are a regression corpus, not a measurement of accuracy across the Python ecosystem.
See the Python roadmap and observed limits before using results in CI policy.
License
MIT. See LICENSE.
Metadata
Release files for depreach 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| depreach-0.2.0.tar.gz | 783.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| depreach-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 880.3 kB
Release files / depreach-0.2.0.tar.gz
| Download URL | depreach-0.2.0.tar.gz |
|---|---|
| Size | 783.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
58253c9e1161d7c37054b4fa3de0057c7fc047e9483c8ca3ab4b4761e5366d7c
|
|
BLAKE2b-256 checksum How to use checksums |
ab3aac3d2000f21247404993687c7622e12b39fe1233e733fcbb85310d599d62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.17
|
Release files / depreach-0.2.0-py3-none-any.whl
| Download URL | depreach-0.2.0-py3-none-any.whl |
|---|---|
| Size | 97.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85afa7a0be2c96bd4b0ae6d091694fd450d8944a83fa18c1211f2870cd0d1eab
|
|
BLAKE2b-256 checksum How to use checksums |
e5867a81637010ab5be2e5dd42e5ed766ecf10ff393c4787e2d4ac21a25fd243
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.17
|