
KEVin wraps CISA's Known Exploited Vulnerabilities Catalog in a Flask REST API with merged NVD and MITRE enrichment, built for defenders tracking actively exploited CVEs in authorized environments.
| Tool | synfinner/KEVin — self-hostable REST API over the CISA Known Exploited Vulnerabilities Catalog with NVD/MITRE data merging |
| Category | Vulnerability intelligence API (Python/Flask, MongoDB backend) |
| Primary Use | Querying KEV entries by CVE ID, pulling recent additions via /kev/new/7, and enriching CVEs with merged CISA/MITRE/NVD data through /vuln/<cve_id> |
| Safe Use | Defensive vulnerability management and patch prioritization during authorized security assessments, SOC enrichment pipelines, and lab deployments |
| Telemetry Note | Entirely defensive and read-only: pulls public CISA/NVD/MITRE data. Self-hosted instances leave MongoDB and Redis activity; the public host logs nothing attacker-relevant since no third-party systems are touched |
KEVin describes itself, without much modesty, as "the missing API" for CISA's Known Exploited Vulnerabilities Catalog, and the description is not far off. The KEV catalog is one of the highest-signal prioritization feeds in defensive security — a curated list of vulnerabilities CISA has confirmed are being actively exploited — yet it ships primarily as a web page and a JSON blob. What synfinner/KEVin does is turn that feed into a queryable Flask REST service backed by MongoDB, so a vulnerability management program, a SOC enrichment pipeline, or a reporting toolchain can hit structured endpoints instead of scraping and re-parsing the raw catalog on every refresh.
The core feature set is deliberately narrow and well-scoped. You can fetch a single KEV entry by CVE identifier via /kev/CVE-2023-1234, dump the full catalog with /kev, ask what was added in a recent window with /kev/new/7, and run free-text search across KEV data with /kev?search=Microsoft. Beyond the catalog itself, the /vuln/<string:cve_id> endpoint merges CISA, MITRE, and NVD data for a given CVE, with a /vuln/<cve_id>/nvd shortcut when you only want the NVD slice. That merge is the practical value: KEV tells you what is exploited, NVD gives you CVSS context and references, and MITRE ties into broader taxonomies — one call instead of three.
Architecture-wise, the README reveals more operational maturity than you might expect from a 27-star repo. Data flows in through update.py, which pulls from CISA and populates the local MongoDB; the web tier is a Flask app that reads from that store. The author runs a public instance at kevin.gtfkd.com with edge caching set to three hours and rate limits in place, plus a dedicated status page at kevinapi.statuspage.io. For most defensive teams, the self-hosted path is the sensible one — it removes dependence on someone else's rate limits and keeps query patterns (which reveal what your organization is patching) entirely internal.
The deployment story is straightforward Pythonops: create a virtual environment with python3 -m venv env, activate it, and pip3 install -r requirements.txt. Configuration lives in a .env file, and the README walks through the relevant keys in detail. You need an API_KEY from NVD (free, from the NVD developers portal) for the enrichment endpoints, plus MONGODB_URI_PROD or MONGODB_URI_DEV connection strings. A Docker path is also provided via a docker-compose.yml that builds the Flask app and maps port 8444, with restart: unless-stopped — a reasonable pattern for a long-running internal intelligence service.
What stands out most in the README is the caching layer, which is documented with unusual depth. The environment block exposes ORIGIN_RATE_LIMIT_WINDOW_SECONDS, UNCACHED_QUERY_RATE_LIMIT for list and recent-KEV cache misses, and POINT_MISS_RATE_LIMIT for point, RSS, and metrics misses. Redis enforces shared per-window limits across workers, while fill locks (CACHE_FILL_LOCK_SECONDS) serialize origin fetches using owner tokens to prevent thundering-herd refreshes of the same key. CACHE_SINGLEFLIGHT_WAIT_SECONDS defaults to zero so a contended key fails fast rather than queueing, and CACHE_TTL_JITTER_RATIO spreads expiry times using secrets.randbelow to avoid synchronized cache expiry spikes.
The negative-caching design is equally considered. Manual point resources keep at most NEGATIVE_CACHE_MAX_ENTRIES (default 1024) short-lived local misses as an L1 in front of Redis, governed by NEGATIVE_CACHE_TIMEOUT. Cached 2xx and 4xx responses share the same TTL, and — notably — high-cardinality /kev search and actor variants deliberately stay out of Redis, falling back to a bounded in-process cache for exact repeats. This is the kind of engineering you write after running a public endpoint and watching what unbounded search does to your backend, and it is a useful reference implementation even for people who never deploy KEVin itself.
There are a few security-relevant details operators should absorb before standing up an instance. TRUSTED_HOSTS is a comma-separated allowlist of accepted HTTP Host headers, read once at startup — a correct mitigation against Host-header injection into generated links, and you should include the hostnames your local health checks and reverse proxies use. PUBLIC_BASE_URL sets the canonical origin for homepage metadata. Most importantly, the README's Considerations section is blunt: you should not expose MongoDB to the broader internet. The compose file places the app on an external gtfkdProd network with only port 8444 published, leaving Mongo on the internal network — follow that pattern.
From a defensive workflow perspective, KEVin slots neatly into patch-prioritization logic. The single most common question in vulnerability management is "which of our findings are actually being exploited?" — and the KEV catalog is the authoritative public answer. A scheduled update.py run keeps the local store current, /kev/new/7 feeds a weekly triage digest, and per-CVE lookups enrich scanner output during report writing. For authorized pentest teams, the same endpoints provide evidence-backed severity justification: citing KEV presence for a CVE you flagged elevates the finding from theoretical to actively exploited in the wild.
The MITRE and NVD enrichment also means KEVin can serve as a lightweight single-pane CVE lookup for less technical stakeholders, who get one JSON response instead of three websites. The public host is fine for ad-hoc research, but any team wiring this into automation should mirror the repo locally — both for rate-limit headroom and because the author candidly notes limited time for improvements, making the contribution path (issues and pull requests are welcomed) the realistic mechanism for change.
As with any intelligence aggregator, the usual caveats apply: KEV reflects CISA's confirmed-exploitation bar, which is deliberately conservative, so absence from the catalog is not evidence a CVE is safe — only that exploitation is not yet confirmed. KEVin makes no claims otherwise; it is a clean, defensively-oriented accessor for public data, with caching engineering well above its weight class, and it earns a spot in the internal-tooling shelf of any team that takes vulnerability prioritization seriously.
synfinner/KEVin.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
Related coverage
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.