I wanted to make the EU Cyber Resilience Act Article 14 question answerable in ten seconds, without installing anything.
So: cra.toledotechnologies.com/check — paste a package-lock.json, requirements.txt, go.sum, Cargo.lock, Gemfile.lock, composer.lock, gradle.lockfile, or a CycloneDX/SPDX SBOM. Get an answer.
The question it answers
Since 11 September 2026, Article 14 of the CRA has been enforceable: if a vulnerability in a product you've placed on the EU market is being actively exploited, you owe an early warning to your national CSIRT and ENISA within 24 hours of becoming aware.
The operative word is exploited. Not "critical". Not "CVSS 9.8". Not "there's a PoC". That distinction is the entire ballgame, and it's why your scanner's severity-sorted output is answering a different question than the regulator is asking.
The checker resolves your declared dependencies against OSV.dev, maps every advisory to its CVE aliases, and intersects that with the CISA KEV catalogue.
Nothing is uploaded
It runs entirely in your browser. Your file contents never reach a server of mine — package names and versions go to the public OSV.dev API for lookup, and the KEV comparison happens locally in the page. No account, no logging, no backend of mine involved at all.
One implementation note that might save you time if you build something similar: CISA's KEV feed sends no CORS headers, so you cannot fetch it from a browser. I mirror it same-origin (US Government work, public domain) with explicit provenance fields in the JSON so the copy can't be mistaken for the authoritative source. OSV.dev does send CORS headers and can be called directly from the client.
What you get
Clean:
No known-exploited components found
Checked 3 components against KEV catalogue 2026.09.11 (1709 entries).
3 component(s) do carry published advisories that are not on the KEV
list. That is ordinary patching work — not a reporting clock.
Not clean:
2 known-exploited components — decision required
CVE-2021-45046 org.apache.logging.log4j:log4j-core 2.14.1 Known
CVE-2021-44228 org.apache.logging.log4j:log4j-core 2.14.1 Known
Early warning 24 hours 2026-09-15 09:30:26 UTC
Notification 72 hours 2026-09-17 09:30:26 UTC
Final report 14 days 2026-09-28 09:30:26 UTC
What it deliberately doesn't claim
A KEV hit does not mean you must file. KEV evidences exploitation somewhere in the world; Article 14 asks about exploitation in your product. If the vulnerable path isn't reachable in your build, the answer may be no — and the Commission's July 2026 guidance is explicit that reachability matters for third-party components. No scanner can make that call.
Equally, a clean result is not a certificate. KEV lags and isn't exhaustive. Your own telemetry or a customer's incident report can start the clock before CISA lists anything.
Whatever the result: write down what you knew and when you knew it. A documented decision not to report is defensible. An undocumented one isn't.
CLI version
For CI, the full tool walks your whole repo across twelve lockfile formats and exits non-zero on a match — github.com/ntoledo319/cra-watch, MIT, stdlib only:
- uses: ntoledo319/cra-watch@v1.0.0
with:
fail-on-match: 'false'
Run it on a schedule, not just on push. The KEV catalogue grows continuously — a repo that was clean yesterday can become a reporting question today with no change to your code.
If you hit a lockfile format it mangles, open an issue. I'd rather fix it than be confidently wrong in public.
Not legal advice; I'm not a lawyer. Verify against Regulation (EU) 2024/2847 and your coordinating national CSIRT before filing.
Top comments (0)