CRA and NIS2 evidence for WordPress: software inventory, SBOM export, vulnerability monitoring and a readiness checklist. Monitoring works out of the box, with no account or API key.
Why now
The EU Cyber Resilience Act's reporting obligations have applied since 11 September 2026 (24h/72h/14d incident reporting), and the main obligations apply from 11 December 2027. The CRA covers products with digital elements sold in the EU, and NIS2 covers organisations in certain sectors above certain sizes, which can reach their suppliers. Many websites fall under neither; if yours does, the evidence trail is worth starting now.
The tabs
- Dashboard - readiness score, open findings, monitoring status and the data source in use.
- Inventory & SBOM - every plugin, theme and core with versions; export as a CycloneDX SBOM. With WPVulnerability as the source, each row shows whether its last vulnerability check succeeded.
- Findings - known vulnerabilities in your installed versions, with severity, CVSS score and CVE links. A resolved vulnerability that comes back (for example after a downgrade) is reopened, logged as evidence and alerted again; an ignored one stays ignored.
- Checklist - CRA readiness items with pass/attest states.
- Evidence - a log of compliance-relevant events (scans, detections, resolutions, attestations, source changes, components that could not be checked, alerts the mail system refused).
- Settings - data source, Wordfence token, vulnerability alerts and their recipients, and the uninstall opt-in.
Vulnerability data sources
Choose one under Settings > Vulnerability data source.
- WPVulnerability (default) - no account needed. Each scan looks up every installed plugin and theme by its slug, and WordPress core by its version, on www.wpvulnerability.net. Plugin and theme versions are compared on your server. Answers are cached for 12 hours, so repeated scans do not repeat requests. Data is published under CC0 1.0; the Findings tab credits WPVulnerability.
- Wordfence Intelligence - needs your own free API token from wordfence.com (Dashboard > Integrations). Each scan downloads the whole Community Edition feed with your token and matches it on your server.
Sites that already had a Wordfence token saved before 1.1.0 keep Wordfence; everyone else starts on WPVulnerability. A site updated from an earlier version that had vulnerability data but no saved token moves to WPVulnerability, and that switch is recorded in the evidence log at the next scan.
Switching source is recorded in the evidence log. The two sources use different identifiers, so at the next scan with data the findings from the old source get the status Closed: data source changed (never "Resolved", so no false fix evidence) and the new source's findings are recorded. An issue both sources report - same component and same CVE - is not alerted again, and stays ignored if you had ignored it. Findings on a component the new source could not check yet stay as they are until a later scan checks it.
When a lookup fails
A component whose lookup fails (the service is unreachable, times out, answers with an error other than "invalid slug", or sends an answer that cannot be read) is shown as not checked:
- a notice on the Dashboard and Findings tabs names it,
- its Inventory row says "Not checked",
- one "Some components could not be checked" entry is written to the evidence log per scan,
- its open findings stay open and are never resolved on missing data,
- the "No open critical vulnerabilities" checklist item does not pass.
The next scan tries again. A scan spends at most about 20 seconds on lookups; if components are left, a follow-up scan is queued a couple of minutes later and continues from the cache. After three connection failures in a row the scan stops asking and marks the rest not checked.
Checked - not in the database
Some components cannot be in a database keyed by WordPress.org slugs. They are counted as checked with nothing found, shown as Checked - not in the database in the Inventory, and do not trigger the not-checked notice or hold back the checklist:
- a plugin or theme folder whose name cannot be a WordPress.org slug (a space, a plus sign or brackets in it), and one WPVulnerability refuses as an invalid slug,
- a custom single-file plugin (a lone
.phpfile in the plugins folder). It is never looked up by its file name. Hello Dolly (hello.php) is the exception and is looked up ashello-dolly.
A WordPress beta, release candidate or alpha (for example 7.2-RC1) is looked up under the release it leads up to (7.2), and what that release lists is applied to the installed pre-release.
WPVulnerability can list one WordPress core issue once per source (CVE, EUVD, Wordfence). Entries with the same CVE are shown once, and an entry without a CVE is dropped when its description matches a CVE entry. Copies worded differently can still appear as separate findings.
Alerts
New critical findings are emailed, and so are new findings whose severity the data source has not published yet: those follow the critical ones in the same email, each marked "severity not published - review it". High, medium and low findings are not emailed. By default the email goes to the site admin address. Under Settings > Alert recipients you can enter up to 20 addresses, one per line or separated by commas; each gets its own email. A list containing an invalid address, or the characters < or >, is refused whole and nothing on the form is saved, so no address is ever dropped silently. If the mail system refuses an alert, the evidence log records which addresses it was not handed to.
The "No open critical vulnerabilities" checklist item counts only open findings with a published critical severity. A finding whose severity has not been published does not make it fail, so review those on the Findings tab.
Data & privacy
Findings, the evidence log and all matching stay in your WordPress database.
- With WPVulnerability, requests carry only the component type and slug (and, for core, the WordPress version). Your site address is not sent: requests identify themselves as
DragonCompliance/<version>rather than WordPress's default user agent, which includes the site URL. The service sees your server's IP address, as with any request. Privacy policy: https://www.wpvulnerability.com/privacy/ - licence: https://www.wpvulnerability.com/license/ - With Wordfence Intelligence, only your token is sent, to www.wordfence.com. No other host is ever used for the feed.
Uninstall keeps your evidence by default - evidence you can lose by uninstalling isn't evidence. Cached vulnerability answers are always removed on uninstall.
For developers
dragoncompliance_feed_source(filter) adjusts the Wordfence request; the URL must stay HTTPS on www.wordfence.com or the default is used. It applies only while Wordfence is the chosen source.dragoncompliance_feed_failed(action,WP_Error $error, string $url) fires when the Wordfence feed refresh fails, and once per failed WPVulnerability lookup with that lookup's URL.dragoncompliance_vuln_detected,dragoncompliance_vuln_resolved,dragoncompliance_scan_completefire as before; the scan summary now includesnot_checkedandcarried_over. After a source change, an issue the old source already reported (same component and CVE) is logged but does not firedragoncompliance_vuln_detected.
Uninstall
Deleting the plugin keeps all its data by default, so a reinstall picks up where you left off. To remove everything on uninstall, tick "Delete data on uninstall" under Settings, or opt in from WP-CLI first:
wp option update dragoncompliance_delete_data_on_uninstall 1