Skip to content

Releases: markrusselldev/auditor

auditor 0.11.0

Choose a tag to compare

@markrusselldev markrusselldev released this 18 Oct 10:23

Added

  • 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.

v0.10.0

Choose a tag to compare

@markrusselldev markrusselldev released this 11 Sep 22:44

Dogfooding the pipeline on real cohorts surfaced a scan-scope bug and several
false-positive classes; this release fixes them and unifies the batch and web paths
onto one pipeline behind a single scan command.

Changed

  • The scan batch command now runs the full audit pipeline - the same scan_url the web tool
    runs - over every site in a CSV, so a batch and the live site exercise identical code. Each site
    runs in its own subprocess with a hard --per-site-timeout, and --workers sites run in parallel
    (the Playwright sync API is not thread-safe, so scans are isolated by process, not thread). It
    replaces the previous static-crawler behavior of scan.
  • scan is now the only command on the auditor CLI. The older audit-v2 command is archived in
    auditor.legacy_cli (not deleted, just off the main CLI; run via python -m auditor.legacy_cli audit-v2). The deep-revenue path's browser verification, previously reached by spawning the
    browser-verify command, now uses a dedicated internal worker (auditor.browser_verify_worker)
    that calls the verifier directly - an internal process, not a user command.

Fixed

  • Reachability checks now stay on the audited site. When a donation, ticketing, or
    contact link leads to an external platform, the scan confirms the link resolves and
    stops there instead of following it into the third-party site. This keeps scans fast
    and focused on the site being audited, and prevents an external platform's own page
    content from being read as a finding.
  • Reachability now honors a per-site time budget, so a site with a large first-party
    ticketing or events section can no longer run away with the whole scan; the check
    stops once the budget is spent and reports on the controls it verified. Configurable
    via AUDITOR_REACHABILITY_BUDGET_SECONDS (default 60; 0 disables the limit).
  • A contact or signup form that submits to a hosted third-party endpoint (Mailchimp,
    PayPal, and similar) is no longer reported as broken. Those endpoints answer a
    health-check GET with a 404 while still accepting real submissions, so only a dead
    endpoint on the site's own domain is flagged now.
  • Embedded third-party content (video, donation or ticketing widgets) and third-party
    images are no longer reported as broken when they fail only under the automated
    render; those platforms often block or lazy-load for an automated visit while serving
    real visitors normally. A genuine failure of the site's own assets is still caught.
  • A page that loads and then immediately redirects is no longer misreported as
    unreachable; only a page whose navigation genuinely fails is flagged.
  • A finding names a control by a short label instead of quoting a whole sentence of
    link text when an entire sentence is wrapped in a link.
  • A live donation page is no longer flagged solely because its page copy contains the
    word "demo"; the test/sandbox check now requires an explicit environment indicator
    (for example, "test mode" or "sandbox mode").
  • The www vs non-www check now runs only on a real registered domain. A site served from
    a subdomain - a department page, or a store hosted on a platform like Square or Shopify -
    is no longer flagged for a missing "www" address that no visitor types and the owner
    cannot set up.
  • A form is reported as unsubmittable only when it has two or more text fields and no way
    to send it. A single search box (which submits on Enter), a filter dropdown (which acts
    on selection), and a form whose submit control is a styled link or role=button (as page
    builders like Divi and Elementor use) are no longer misreported as broken.
  • A search or other GET form is checked at the address it actually submits to, carrying its
    own fields, rather than the bare action URL. A search endpoint that answers a bare request
    with a 404 but works with a query is no longer flagged.
  • Mobile navigation is judged usable when the site's links are visible and tappable, even
    when they are not wrapped in a nav landmark (a full-width stacked menu with no hamburger).
    It is flagged only when the primary destinations are genuinely unreachable on a phone.
  • A broken-image finding now says whether it is a content image (the broken-image icon a
    visitor sees) or a background image (a missing texture), and marks a third-party asset as
    such instead of blaming the phone breakpoint for it.
  • A page that fails to load during the crawl is re-checked before being reported. A login
    page that loops a cookie-less crawler (a Shopify customer-account page redirects to
    Shopify's own login), a rate-limited response, and a momentary connection blip are no
    longer reported as broken pages; a genuinely dead page still is.
  • A booking, donation, or contact link whose destination fails to load during the scan is
    re-checked before it is called a broken revenue path, so a momentary DNS or connection
    blip is not reported as a dead link.
  • Mobile horizontal-scroll (reflow) is now flagged only when a visible, on-screen element
    genuinely extends past the phone viewport, measured after the page settles. Off-screen or
    hidden menus, elements clipped by an ancestor, a layout that is briefly wide only during
    load, and the Google reCAPTCHA badge no longer count as overflow.