Repository navigation
Behavioral scanners (setup.py, native binaries, version diff) + severity model docs - #233
Merged
ALLEN-AYODEJI merged 5 commits intoOct 20, 2026
Conversation
PyPI sdists execute setup.py at install time, making it the direct analogue of npm install scripts. Adds the behavioral analysis module and its first detector: a line-based scan (no Python AST) that strips # comments, then flags subprocess usage (calls and imports), os.system(), exec()/eval(), base64.b64decode() (including direct b64decode imports), and urllib/requests calls. Each hit is a BehavioralFinding carrying the 1-based line number; command-execution signals rate high and obfuscation/network calls rate medium per docs/severity.md. Dependency names such as install_requires=["requests"] are not calls and do not trigger. Closes DepRadarOrg#103
Prebuilt executables in an npm or PyPI package cannot be code-reviewed the way source can, and dropped binaries are a common payload carrier. scan_binaries walks an unpacked package tree and reports every file carrying an ELF, PE or Mach-O magic header, or with a native extension (.exe, .dll, .so, .dylib, including versioned libfoo.so.1). Magic bytes are sniffed before extensions are consulted, so an extension-less ELF is still caught. Emits one low-severity informational finding listing all binaries - a review prompt, not a red flag, since real projects ship legitimate native addons. Closes DepRadarOrg#104
The most useful supply-chain signal is often what changed: a patch release that adds an install script or network code. diff_versions(old, new) compares two unpacked package trees and reports added/removed files, install scripts present in new but not old (a root setup.py, or npm preinstall/install/postinstall entries in package.json), and suspicious setup.py calls new in new. Calls are matched by file and kind rather than line, so ordinary line shifts from a version bump create no noise. PackageDiff::is_clean() is true when only benign files changed. Closes DepRadarOrg#105
Contributors adding detectors need one place that defines what low, medium, high and critical mean in DepRadar. Adds docs/severity.md: a definition per level, a rated example per FindingKind (homoglyph typosquat -> critical, distance typosquat -> high, vulnerability -> its advisory level, unrated advisory -> high) and per behavioral signal (setup.py command execution -> high, obfuscation/network -> medium, native binaries -> low, new install script between versions -> medium), the CVSS v3 qualitative mapping (0.0-3.9 low, 4.0-6.9 medium, 7.0-8.9 high, 9.0-10.0 critical) with the label fallback, how severity flows into --fail-on, SARIF levels and security-severity, and guidance for detector authors. Linked from README and CONTRIBUTING; all commands and links verified. Closes DepRadarOrg#106
|
@iam-mercy Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds the first three behavioral-analysis detectors (
src/behavioral/) plus the severity-model documentation they are rated against. Behavioral detectors analyze the contents of an unpacked package, complementing the existing name-based (typosquat) and advisory-based (CVE) checks.setup.py#103 —setup.pysuspicious calls (src/behavioral/setup_py.rs): a line-based scan (quote-aware#-comment stripping, no Python AST) flaggingsubprocessusage (calls and imports),os.system(),exec()/eval(),base64.b64decode()(including directb64decodeimports), andurllib/requestscalls — each emitted with its 1-based line number. Command-execution signals rate high, obfuscation/network medium. A normal setuptoolssetup.py(incl.install_requires=['requests']) scans clean.src/behavioral/binaries.rs):scan_binarieswalks an unpacked package tree and reports ELF/PE/Mach-O magic headers plus.exe/.dll/.so/.dylibextensions (incl. versionedlibfoo.so.1), emitting one low-severity informational finding listing them.src/behavioral/diff.rs):diff_versions(old, new)reports added/removed files, new install scripts (rootsetup.py, npmpreinstall/install/postinstall), and new suspicioussetup.pycalls, matched by file and kind so line shifts from a version bump don't create noise.docs/severity.md): defines low/medium/high/critical with a rated example perFindingKindand per behavioral signal, the CVSS v3 qualitative mapping, the label fallback, how severity flows into--fail-on/SARIF, and guidance for detector authors. Linked from README and CONTRIBUTING.Behavioral findings are their own
BehavioralFindingtype (files inside one package, not lockfile dependencies) but reuse the sharedSeverityenum, so reports can rank them uniformly. No existing public API or output format changes.Related Issues
Closes #103
Closes #104
Closes #105
Closes #106
Type of Change
Testing Done
All commands run locally against the branch tip (CI parity):
cargo fmt --all -- --check— cleancargo clippy --workspace --all-targets --locked -- -D warnings— cleancargo test --workspace --locked— 13 test binaries, 0 failures (20 new behavioral unit tests among them)cargo test -p deprader --features async --locked— passes (CI's second test job)cargo build -p deprader-router --target wasm32v1-none --release --locked— passes (contracts/ untouched; CI wasm job)New tests:
setup_py: clean setuptools file (no findings) + malicious sample flagged at exact line numbers; comment/#-in-string handling; lookalike identifiers (peval,os.system = ...); per-line dedupe; directb64decodeimport.binaries: fake headers for each format (ELF, PE, 64-bit LE + 32-bit BE Mach-O); extension matching incl.libfoo.so.1.2.3; mixed nested tempdir tree; informational finding severity/list; clean package.diff: fixture pairs undertests/fixtures/behavioral/— v1 clean vs v2 malicious sdist (headline case), identical trees, docs-only bump, pre-existing calls not re-reported, new npmpostinstall.Checklist
cargo fmt --allandcargo clippy --workspace --all-targets -- -D warningsare cleancargo test --workspace --lockedpassescontracts/changed (not applicable —contracts/untouched)