Skip to main content

vulnfind

github.com/codingsushi79/vulnfind

A zero-dependency security scanner for code, websites, container images and cloud accounts, with ranked results that tell you what to fix first.

vulnfind ~/code/my-app                 # your code
vulnfind github.com/owner/repo         # someone's repo, by URL (shallow clone, nothing executed)
vulnfind https://my-site.com           # a website you own
vulnfind image my-app:latest           # a container image
vulnfind k8s · vulnfind cloud aws      # a live cluster / cloud account (read-only)

Python 3.8+. The core needs no third-party packages; the optional AI explanations use the official anthropic SDK.

uv tool install git+https://github.com/codingsushi79/vulnfind      # or: pipx install git+https://github.com/codingsushi79/vulnfind

What it finds

In your code (vulnfind <folder>)

Scanner Depth
deps Known CVEs, GHSA advisories and malicious packages from OSV.dev across 10 ecosystems, enriched with CISA KEV (exploited in the wild) and EPSS (exploit probability). For each package it shows the dependency chain (express › body-parser › qs), whether it's direct, whether your code imports it, and whether your code calls the vulnerable function (exact symbols for Go; names from the advisory text otherwise, labelled as a heuristic). Plus typosquats, suspicious npm install scripts, deprecated and abandoned packages, license conflicts (GPL/AGPL in a permissive or proprietary project), missing lockfiles and unpinned requirements.
secrets 45+ credential formats plus generic passwords, filtered by entropy and placeholder detection, always masked in output. --history checks every commit, so deleted-but-still-in-git secrets are found along with the commit that added them.
code Data-flow analysis. Python (AST, across files: views → services → db), JavaScript/TypeScript, Go and PHP: user input is traced through variables, string building and helper functions into SQL, shell, eval, deserialization, templates, the filesystem, outbound HTTP, redirects and HTML. Sanitizers and constants are understood, so their lines aren't flagged. Route inventory and missing-auth detection for Flask, FastAPI, Django REST, Express-style routers and Next.js (vulnfind routes); auth helpers are recognized one call deep. Each data flow says whether an anonymous user can reach it. ~100 more pattern rules across 10 languages.
config Dockerfile, compose, Kubernetes, Terraform and Terraform plan JSON, GitHub Actions (pwn requests, script injection, unpinned actions), pip dependency confusion, end-of-life runtimes…
files Key stores, .env, Terraform state, dumps, world-writable files, with git awareness (tracked, ignored, about to be committed).

On a website (vulnfind <url>, see Website scanning)

TLS and certificates, security headers, cookies, CORS, debug pages, ~50 exposed-file probes, server software CVEs from version banners (NVD), vulnerable front-end JS libraries, secrets in served JS, SPF/DMARC/CAA, login-aware crawling, OpenAPI-driven API auth testing, optional headless-browser rendering, and subdomain takeover detection. With --active, it also confirms reflected XSS, SQL errors and open redirects.

In infrastructure

Command What it checks (read-only)
vulnfind image <ref> Reads a container image layer by layer without running it. Checks: OS packages (Debian/Ubuntu dpkg, Alpine apk, RPM), npm/Python/Java JARs incl. fat JARs, Go binaries' embedded modules, servers compiled from source (Apache, nginx, PHP, Node, Redis, Postgres → NVD), secrets left in the image, root user, secrets in ENV, end-of-life base OS.
vulnfind k8s Workloads (privileged, host namespaces, sensitive hostPath, dangerous capabilities, root, missing limits, unpinned images, plain-text secrets in env), cluster-admin bindings (incl. anonymous), Ingress without TLS, namespaces without NetworkPolicy. Uses your kubectl context.
vulnfind cloud aws Root MFA and keys, IAM users without MFA, old access keys, public S3 (policy, ACL, Block Public Access), security groups exposing admin/database ports, public or unencrypted RDS, IMDSv1, missing CloudTrail. Uses your aws CLI.
vulnfind cloud gcp Firewall rules, public IAM bindings, primitive roles on service accounts, public buckets, Cloud SQL exposure and SSL. Uses your gcloud CLI.
vulnfind tfplan plan.json The same Terraform checks on the planned changes (terraform show -json plan.out); folder scans pick plan files up automatically.

Every finding gets a priority score (0–100) combining severity, exploitation evidence, reachability (imported? function called? reachable without login?), confidence and context. Every report opens with "Fix these first".

Everyday use

vulnfind                              # scan the current folder (live progress on stderr)
vulnfind -v                           # full descriptions, data flows, references, every CVE
vulnfind --plain                      # plain-language explanations for non-security readers
vulnfind --history                    # + secrets anywhere in git history
vulnfind ~/code/*                     # many projects -> one summary table
vulnfind routes                       # HTTP endpoints and whether each requires auth
vulnfind triage                       # walk findings: accept / false positive / ignore rule
vulnfind trend -o trend.html          # how findings changed across past scans (chart)
vulnfind fix --apply                  # upgrade vulnerable deps (requirements, package.json + overrides, go.mod)
vulnfind ai --top 3                   # Claude explains the top findings and drafts patches (optional)
vulnfind watch                        # re-scan on save
vulnfind explain CVE-2021-44228       # an advisory or any rule

Triage once, share the decisions

vulnfind triage saves every decision, with a reason, who made it and when, in .vulnfind-baseline.json. Commit that file: later scans, CI and teammates load it automatically, so accepted risks and false positives stay hidden until the code changes. rule:ID entries go to .vulnfindignore.

AI explanations (optional)

vulnfind ai sends the highest-priority findings to Claude (claude-opus-5-5) together with ±30 lines of the surrounding source, including every file a cross-file flow passes through. For each finding it returns a verdict (real issue vs. likely false positive), the concrete impact, a minimal unified-diff fix, and a way to verify it. Setup: pip install "vulnfind[ai]" plus ANTHROPIC_API_KEY or ant auth login. Requests enable the server-side refusal fallback (fallbacks: "default"), because security-analysis prompts can occasionally trip safety classifiers on benign code. Nothing is sent unless you run this command.

VS Code

editors/vscode is a small extension (needs vulnfind 3.0+ on PATH):

  • Inline findings with severity colors.
  • Data-flow steps shown as related locations.
  • A quick fix that inserts vulnfind:ignore RULE-ID.
  • A status-bar counter; clicking it runs a full scan including dependency CVEs.

Website scanning

Only scan sites you own or have written permission to test.

vulnfind https://example.com                                   # passive
vulnfind web https://staging.example.com --active              # + confirm XSS / SQL errors / open redirects
VULNFIND_USER=qa@example.com VULNFIND_PASSWORD=… \
  vulnfind web https://app.example.com --login-url https://app.example.com/login      # crawl behind login
vulnfind web https://api.example.com --openapi https://api.example.com/openapi.json   # API auth testing
vulnfind web https://spa.example.com --browser                 # render JS (needs: pip install playwright)
vulnfind subdomains example.com                                # CT-log discovery + takeover check

What it's careful about:

  • Passive by default. GET/OPTIONS only, same-origin crawling, and it skips logout/delete-style links. It's rate-limited and capped (--rate, --max-requests).
  • No soft-404 false positives. An exposed-file hit must match a content signature and differ from a random-path baseline.
  • Login safety. Credentials come from environment variables only, so they never land in shell history. It refuses to send them over plain HTTP, to an untrusted certificate (unless --insecure), or to a form that posts to another origin. It also reports two login weaknesses: no CSRF token, and a session ID that isn't rotated at login.
  • OpenAPI testing is read-only. It sends GET operations only, without credentials. An operation the spec says requires auth but that answers anyway is flagged HIGH.
  • Narrow --active mode. It sends harmless markers to GET parameters the crawl already found, never submits POST forms, and stops at a budget.
  • Version-based server CVEs. Matched from the advertised version, never by sending exploits. Distro builds that may carry backported fixes are marked medium confidence.

Automation

Need Command
CI for any repo uses: codingsushi79/vulnfind@main (this repo is a GitHub Action: SARIF upload, PR-diff mode, job summary, grade / findings outputs), or vulnfind ci github --write for a full workflow.
Block bad commits vulnfind hook install scans staged content and keeps any hook you already had. Also available through the pre-commit framework (.pre-commit-hooks.yaml).
Monitor over time vulnfind monitor ~/code/app https://app.example.com image:app:latest --notify $SLACK alerts only on new findings since the previous run. --print-cron gives a crontab line.
PR / branch scans vulnfind --diff origin/main · vulnfind --staged
Gate on regressions vulnfind compare before.json after.json exits 1 if anything new reaches --fail-on.
Alerts --notify URL posts to Slack, Discord, Teams or any JSON webhook. --quiet-ok stays silent unless something fails.
Config as code vulnfind init writes .vulnfind.json (defaults for every flag, plus custom rules) and .vulnfindignore.
Stay current vulnfind update upgrades vulnfind using whatever installed it (uv, pipx or pip).

Custom rules

Add your own regex rules inline in .vulnfind.json ("rules": [...]), per project in .vulnfind/rules/*.json, or for every project in ~/.config/vulnfind/rules/*.json:

{"rules": [{"id": "ACME-NO-INTERNAL-API", "title": "Internal admin API called from a handler", "severity": "high",
            "pattern": "internal_admin_api\\(", "extensions": [".py"], "fix": "Go through the permission-checked service"}]}

Output formats

-f for stdout, or -o FILE (repeatable), with the format taken from the extension: table · json · sarif · github (inline PR annotations) · junit (.xml) · html · markdown · csv · CycloneDX SBOM (.cdx.json).

Exit codes: 0 clean · 1 findings at or above --fail-on (default high) · 2 usage/runtime error.

Accuracy

vulnfind bench measures recall and precision on a labelled corpus. In each file, expect: RULE marks a line that must be flagged and safe marks one that must not. The corpus covers data flows in four languages, secrets, Dockerfile and GitHub Actions issues, plus deliberate traps: sanitized values, constants, parameterized queries, RegExp#exec, placeholder credentials, multi-line templates. Current result: 100% recall, 100% precision (39/39, 0 false positives on 21 safe lines). CI fails below 90%. The corpus is small and hand-written, so treat it as a regression guard, not a guarantee. Real-world findings deserve the same review you'd give any scanner.

Noise control is built in:

  • Comments and strings: code rules ignore both.
  • Confirmed and cleared lines: a confirmed data flow replaces the weaker pattern hit on the same line, and lines the flow engines prove clean are dropped.
  • Context: findings in tests, examples and docs drop one level; bind-parameter SQL is downgraded; placeholder and localhost credentials are skipped.
  • Auth checks: missing-auth findings need evidence that the project uses auth elsewhere.

Privacy & network

  • Folder scans: package names and versions go to OSV.dev and deps.dev, CVE IDs to FIRST (EPSS), and the CISA KEV feed is downloaded. Source code never leaves your machine.
  • Website scans: requests go to the target. Library and server versions go to OSV and NVD (set NVD_API_KEY for faster lookups), DNS lookups to cloudflare-dns.com, and the domain to crt.sh / CertSpotter for subdomains.
  • Image, k8s and cloud: these use your local Docker, kubectl, aws and gcloud tools, read-only. vulnfind never handles cloud credentials itself.
  • vulnfind ai: sends findings and nearby source to the Claude API, only when you run it.
  • History: a one-line summary per scan (counts and grade, no findings) in ~/.local/share/vulnfind (--no-record or VULNFIND_NO_HISTORY=1 turns it off).
  • Turning it off: --offline disables third-party lookups.

Limitations

  • Code: data-flow analysis covers Python across files, and JS, Go and PHP within a file. The JS/Go/PHP engines read code line by line, so unusual code shapes can be missed.
  • Web: a fast baseline, not a penetration test. It doesn't fuzz POST forms or find business-logic flaws, and server CVEs need a visible version banner.
  • Images: Go binaries built with (devel) main modules can't be version-matched, and RHEL/UBI OS packages are inventoried but not CVE-checked (OSV has no feed).
  • Tested against recorded output: the AWS/GCP/kubectl audits (no live accounts were available while building them), Playwright rendering (not installed here) and the AI command (exercised with a stub SDK).

Development

python3 -m unittest discover -s tests     # 152 tests, no dependencies (web tests use a local fixture site)
python3 -m vulnfind bench                 # precision / recall on the labelled corpus
python3 tests/web_fixture.py 8090         # a deliberately vulnerable local website to scan

Rules are data: vulnfind/scanners/{secrets,code,iac,files}.py, taint sinks in taint_python.py / taint_js.py / taint_lines.py, web probes in vulnfind/web/paths.py. Add a labelled case to vulnfind/bench/cases/ with every new rule.

Metadata

Release files for vulnfind 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vulnfind 3.0.0
File Size Uploaded Provenance Actions
vulnfind-3.0.0.tar.gz 252.4 kB Without provenance Details for vulnfind-3.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for vulnfind 3.0.0
File Interpreter ABI Platform Actions
vulnfind-3.0.0-py3-none-any.whl Python 3 none any Details for vulnfind-3.0.0-py3-none-any.whl

Total release size: 498.7 kB

Release files / vulnfind-3.0.0.tar.gz

Download URL vulnfind-3.0.0.tar.gz
Size 252.4 kB
Tags Source
SHA-256 checksum
How to use checksums
3bf728154f1f9d45e47727cfba951312ba32258b7909b73a1cd3f12398c6d4f4
BLAKE2b-256 checksum
How to use checksums
9b3a54e3ccbfdf5fec0552042e033e992e059e891611949036f09366daab5e2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / vulnfind-3.0.0-py3-none-any.whl

Download URL vulnfind-3.0.0-py3-none-any.whl
Size 246.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d3fcdafa1413d76f8a01bf55b406131290d67b3abb17f5314b5506aac8bdc4b1
BLAKE2b-256 checksum
How to use checksums
449977b6c566dafcf36df79624852eddee963c120a0c82daee7859208679a02d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for vulnfind 3.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page