Security Auditor — renders the audited page in a headless Chromium, looks for a visible cookie consent banner and checks that it lets visitors both accept and reject non-essential cookies.
Privacy
Visitors in the EU, the UK and many other places must be asked before non-essential cookies are set, and a real choice means a reject button, not only an accept one.
Rendered pages
Consent banners are injected by JavaScript, so the page is loaded in a real browser, the network is allowed to go idle and the accept button is clicked to count the cookies it sets.
How it works
- Render — launches a headless Chromium as 37AuditsBot, navigates to the audited URL, waits for the network to go idle and then two more seconds so consent scripts can inject their banner. A blocked navigation (HTTP 403, HTTP 429 or a Cloudflare challenge) ends the audit with
590; a navigation that returns no response or an HTTP status of 400 or more ends it with500; a browser failure, after one relaunch when Chromium crashes, ends it with501. - Find the banner — queries sixteen common selectors (
[class*='cookie'],[id*='consent'],[class*='gdpr'],[role='dialog'],.cookie-banner,#cookieConsentand the like) and takes the first visible match per selector as the banner; hidden elements do not count. The text and the button labels of each banner are recorded. - Find the choices — reads the text of every
button,a[role='button']andinput[type='button']on the page and looks for accept keywords (accept,allow,agree,ok,enable,yes,continue), reject keywords (reject,decline,deny,disable,no,refuse,essential only,necessary only) and settings keywords (settings,preferences,customize,manage,options,choose). Links whose text orhrefmentionprivacy,policy,gdprordata protectioncount as a privacy policy link. - Count the cookies — records the cookies present after the page loaded, flags likely tracking cookies (
_ga,analytics,track,_utm,facebook,google) set before any consent, and, when a banner with an accept option exists, clicks the accept button, waits two seconds and counts the cookies again. - Rules — no visible banner fails (
400); a banner with an accept option but no reject option (300), with a reject option but no accept option (301) or with neither (302) warns. - Aggregate — FAIL wins over WARNING; when the banner offers both choices the audit is
SUCCESS(200) and the message names the mechanism, the buttons and the cookie counts before and after accepting.
What it audits
Every row maps to onecheckRule* method and one CheckCode, in the order the auditor runs them. CheckCode suffixes use status ranges: 200 success, 300–399 warning, 400–499 fail, 500–599 error.
Every check carries the data the browser collected:
hasConsentBanner, hasAcceptOption, hasRejectOption, hasSettingsOption, consentMechanism (None, Granular, Binary Choice, Accept Only or Banner Only), hasPrivacyPolicyLink, bannerText, availableOptions, detectedBannerSelectors, cookiesBeforeConsent, cookiesAfterAccept, cookiesAfterReject, their three counts and blocksNonEssentialByDefault.
Output documentation
Risks and considerations
Why consent matters
- The ePrivacy Directive, the GDPR and the UK PECR require consent before non-essential cookies (analytics, advertising, social media) are set, and regulators have said that consent is only valid when rejecting is as easy as accepting.
- Consent collected through an accept-only banner can be declared invalid, which turns every cookie set under it into an unlawful one.
- Similar rules exist outside Europe (Brazil’s LGPD, several US state laws), so the banner is rarely optional for a site with international visitors.
How the detection works, and its limits
- The banner is found by selector: an element whose class or id contains
cookie,consent,gdprorprivacy, or that hasrole="dialog"orrole="banner". A site header withrole="banner"or a privacy link withprivacyin its class is matched too, so a page without a consent banner can read as having one. - The accept, reject and settings buttons are looked up on the whole page by keyword, not only inside the banner: an unrelated
OKorNobutton counts, and a banner whose buttons use other words (Got it,I understand) is not recognised. - The page is rendered with the bot’s user agent from one location, so a banner shown only to EU visitors, or hidden from bots, is not seen.
- Only the accept button is clicked. The reject path is not exercised, so cookies set after rejecting are not measured;
cookiesAfterRejectrepeats the cookies seen before consent. - Granular settings (
Manage preferences) are recorded inhasSettingsOptionand theGranularmechanism name but do not change the verdict.
Changes from the previous version
- A page that answers HTTP 400 or more is now an
ERROR(500) instead of being audited like any other page; a browser navigation that returns no response is also500. - A browser failure that survives the relaunch is an
ERRORwith code501instead of a code-less check carrying the raw Playwright message. - Every check now carries the audited URL as its resource and a
CheckCode; the verdict severities (no banner fails, a banner missing a choice warns, both choices pass) are unchanged.