Skip to main content

cve-dedup-checker

CI PyPI Python License: MIT

Before you submit a CVE finding to WPScan, Patchstack, or HackerOne, check whether someone already reported it. cve-dedup-checker queries the major free vulnerability databases in parallel and tells you clean, possible match, or confirmed duplicate. Built for security researchers, bug bounty hunters, and disclosure coordinators. All data sources are free; no API keys required.

Databases it queries

Database Auth Notes
NVD (NIST) none REST API 2.0. Keyword and CPE search.
OSV (Google) none Aggregator covering GHSA, PyPA, RustSec, Go, Maven, NuGet, crates.io, and more.
GitHub Security Advisories optional Public. GITHUB_TOKEN bumps rate limit from 60/hr to 5000/hr but is not required.
WPScan none Scrapes the public plugin/theme page.
Patchstack none Scrapes the public vulnerability database page.
CISA KEV none Known Exploited Vulnerabilities JSON feed.
Exploit-DB none CSV index mirrored on GitLab.

All responses are cached locally for 6 hours by default so you can iterate on a finding without re-hammering the free APIs.

Install

pipx install cve-dedup-checker

Or from the latest main:

pipx install git+https://github.com/jashidsany/cve-dedup-checker.git

pipx puts the cve-dedup-checker command on your PATH automatically. Standard pip install also works if you prefer managing your own venv.

Requires Python 3.10 or later.

Use

$ cve-dedup-checker wp-plugin <slug> --class broken-access-control

Exit codes:

  • 0 clean
  • 1 possible match (review required)
  • 2 confirmed duplicate
  • 3 inconclusive (no sources responded - usually a network issue)

Target types

cve-dedup-checker wp-plugin <slug>
cve-dedup-checker wp-theme <slug>
cve-dedup-checker npm <package>
cve-dedup-checker pypi <package>
cve-dedup-checker github <owner/repo>
cve-dedup-checker cpe <cpe-2.3-string>
cve-dedup-checker keyword "<free text>"

Output formats

cve-dedup-checker wp-plugin <slug> --output human      # default
cve-dedup-checker wp-plugin <slug> --output json       # pipe to jq, save to file
cve-dedup-checker wp-plugin <slug> --output markdown   # paste into writeup

Narrow by vulnerability class

Accepts short codes or natural language; the matcher normalizes both:

xss                        sqli                  csrf
ssrf                       rce                   lfi
broken-access-control      info-disclosure       file-upload
deserialization            open-redirect         auth-bypass
cve-dedup-checker npm lodash --class prototype-pollution
cve-dedup-checker pypi django --class sqli

Pipeline use

# Only proceed if clean
if cve-dedup-checker wp-plugin my-plugin --output json > /dev/null; then
  echo "No prior disclosure. Safe to submit."
fi

Watch mode

During an active audit, you can keep an eye on whether a new advisory lands for your target before you submit. --watch re-runs the check on a fixed interval and prints only what's changed since the last run.

cve-dedup-checker wp-plugin my-plugin --class broken-access-control --watch 30m
cve-dedup-checker npm some-package --watch 6h
cve-dedup-checker pypi my-lib --watch 1d
  • Supported units: s, m, h, d (e.g. 300s, 15m, 2h, 1d).
  • Minimum interval is 60s to stay polite to free upstream APIs.
  • State is stored at ~/.local/state/cve-dedup-checker/watch/ (or the OS equivalent).
  • First run establishes a baseline. Subsequent runs print only new or resolved match URLs.
  • Ctrl+C exits cleanly.

Optional config

The tool works out of the box with zero config. If you want a higher GitHub rate limit, create ~/.config/cve-dedup-checker/config.toml:

cve-dedup-checker config-sample > ~/.config/cve-dedup-checker/config.toml

Then uncomment the github_token line. Environment variables GITHUB_TOKEN and WPSCAN_TOKEN also work and take precedence over file config.

Cache management

cve-dedup-checker cache-clear

Cache lives at ~/.cache/cve-dedup-checker/.

How dedup classification works

For every advisory returned from any source, the matcher:

  1. Identifier check - does the advisory text contain the target's slug, package name, or a permutation of it?
  2. Class check (if --class is supplied) - does the advisory text mention the same vulnerability class, via a synonym dictionary (XSS, sanitizer bypass, stored XSS, etc. all fold together)?
  • Both match: confirmed.
  • Only identifier matches: possible (different vuln class, review).
  • No match: clean.

This is deliberately conservative: the tool flags things you might have missed, and you make the final judgment. It will never silently drop a hit you should see.

Limitations

  • Fuzzy matching is keyword-based, not semantic. Review possible matches yourself.
  • Some sources have rate limits on the free tier (NVD is the tightest); the local cache mitigates this for iterative work.
  • This tool is a signal, not a verdict. If it says clean and you suspect a dupe, keep searching (vendor bug trackers, Wordfence Intelligence, security mailing lists, HackerOne hacktivity).

License

MIT - see LICENSE.

Metadata

Release files for cve-dedup-checker 0.1.1

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

Source distribution (sdist)

Source distribution for cve-dedup-checker 0.1.1
File Size Uploaded
cve_dedup_checker-0.1.1.tar.gz 19.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cve-dedup-checker 0.1.1
File Interpreter ABI Platform
cve_dedup_checker-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 47.1 kB

Release files / cve_dedup_checker-0.1.1.tar.gz

Download URL cve_dedup_checker-0.1.1.tar.gz
Size 19.4 kB
Tags Source
SHA-256 checksum
How to use checksums
fd57851e0dea8ebc7215c895434700a4e5b820182a2e80bb65be0441c6525b47
BLAKE2b-256 checksum
How to use checksums
6e53154cd4370410192be5c5f62563405f5d01cbf138bb15053f459b6e7ee680
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / cve_dedup_checker-0.1.1-py3-none-any.whl

Download URL cve_dedup_checker-0.1.1-py3-none-any.whl
Size 27.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bca4346176d5a98e6c2ef91ecf29513265950994f997f0f2f01c9287123288a6
BLAKE2b-256 checksum
How to use checksums
ff5f6ebdcf191764df600332a4815ed3e48f1e9ccd1a1d46e26e3f0e4fcc88c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

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