You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
WordPress security checks, now the first section of the report. On a WordPress site, the scan
reads the core, plugin, and theme versions from the page's own asset URLs and matches them against
a local copy of the Wordfence Intelligence vulnerability feed. Each outdated component is one
finding that names its worst hole and the version that fixes them all. Only a Critical or High
hole, or one exploitable without a login, is a headline finding; lower-risk known issues collapse
into one line. Every vulnerability carries the Defiant and MITRE attribution.
Before reporting a known hole, the scan confirms the version from the component's own readme.txt or style.css. A version it cannot confirm is still reported, at medium confidence.
python -m auditor.wordfence_feed downloads the feed and saves a condensed copy. Scans read only
that copy and never call Wordfence. It skips the download when the saved copy is under 20 hours
old, because the key is rate-limited. Without the copy, the WordPress check reports "not tested".
With owner consent, read-only WordPress exposure probes: xmlrpc.php, user enumeration, a public debug.log, an uploads directory listing, and readme.html version exposure.
A local WordPress test site built to fail (tests/wp-fixture/, Docker), with every probed weakness
switched on (setup.sh exposed) or closed (setup.sh locked), to check the scan both ways.
The batch scan command takes --deep-forms, which runs the owner-consent checks on every site:
the deep form test (fill and submit, delivery always aborted) and the WordPress exposure probes.
The scan recognizes sites built on Wix, Squarespace, Shopify, and Weebly and skips the form checks
on them, because their forms belong to the platform and the owner cannot change how they work.
Every other check still runs on those sites.
The own-site form check reports a working contact form that has no spam protection (no honeypot,
captcha, or anti-spam token), at low confidence. It reads the rendered page, so protection added
by JavaScript counts.
The own-site form check tests client-side validation by submitting an invalid email and empty
fields. A form that lets them through is reported.
Changed
Each report section lists its most serious findings first.
findings.csv from the batch command records every finding. It used to keep only the 8 per section
that the report shows.
Removed
The revenue_submit_no_request finding. The deep form test aborts every request, so "the submit
sent nothing" can never prove a form broken, and it was the most common false alarm. A form whose
submit endpoint is dead is still reported (revenue_submit_dead_endpoint).
Security
The reachability check's browser now launches with the same settings as every other browser
the tool starts: Chromium's sandbox follows AUDITOR_CHROMIUM_SANDBOX, and egress goes through AUDITOR_EGRESS_PROXY when it is set. It used to launch with Playwright's defaults, which turn the
sandbox off and skip the proxy.
Fixed
The owner-consent form test no longer reports a form as accepting invalid input when the form's
own JavaScript refuses that input on the submit event (Divi contact forms work this way).
The owner-consent form test judges each form's spam protection on the page as it loaded. Testing
one form can make a page builder redraw its module, which made the next form read as unprotected.
The owner-consent form test no longer crashes the whole scan when a site's own submit handler
sends the browser to another page.
WordPress versions were misread in several ways, which produced false vulnerability findings:
jQuery's version read as the WordPress version, a bundled library's version read as its plugin's,
build hashes and timestamps read as versions, and a version that a plugin hard-codes on every
release read as the installed one. The scan now reads the core version only from files that carry
it, takes the version most of a plugin's own files agree on, and falls back to the component's own
readme when the page stamp is not a real version.
Vulnerabilities exploitable with no login and no user action were treated as lower-risk unless the
title said "Unauthenticated". The feed's CVSS vector now decides it.
Forms no longer read as broken or unprotected when they are: a Mailchimp signup embed, a newsletter
signup, a Divi or Gravity Forms form wired in JavaScript, a form protected by a honeypot field
whose name contains "honeypot", a custom image captcha, or a hidden human-check field, a closed
pop-up form, or a form whose submit handler sits on a parent element (React and Next.js).
The deep form test no longer calls a POST-only endpoint dead because it answers a GET with 404 or
405, fills an email field found by its name, and leaves hidden honeypot fields empty.
The mobile pass identifies itself as a phone by User-Agent, so a site that serves layouts by
User-Agent is no longer judged on its desktop layout.
The mobile tap-target check measures the real control instead of a hidden 1x1 copy of its label.
A navigation drawer or booking widget with "overlay" in its class name is no longer reported as a
blocking overlay unless it covers the middle of the screen.
The mobile menu check tries every plausible menu button, fires the site's own handler when a click
is intercepted, and retries once for a menu that loads late, before it reports the menu broken.