Compliance checklist
What laws and common sense expect from a website: cookies and trackers before the visitor agrees, required pages, accessibility, site and server security. Each item explains why it matters, how to check it yourself, what to give an AI assistant and how to fix it.
These are technical checks, not legal advice. An item says what was found or not and points to the rule, but it does not decide whether the site is lawful. When in doubt, ask a lawyer.
Items: 58. Click an item to open the explanation.
Cookies, trackers and third-party services
What the site does before the visitor agrees. In Germany this is the most common reason for legal complaints.
Cookies are set before the visitor agrees
Why it matters
In the EU a site may set without consent only the cookies it cannot work without (cart, login, language). Analytics, advertising and marketing cookies come only after "Accept". This is the most common reason for complaints against sites in Germany. In the UK, since 5 February 2026, analytics may also run without consent — if it only produces statistics for your own site, the data goes no further and visitors can opt out at any time; advertising still needs consent.
How to check it yourself
Open the site in a private window and do not touch the banner. In developer tools (F12) → Application (Storage in Firefox) → Cookies, see what has already been written. Anything not needed for the site to work is a finding.
How to fix
Turn on blocking before consent in the banner (Cookiebot, Usercentrics, Borlabs and Complianz have a setting for it) or remove the scripts that set cookies. Cookieless analytics (such as the monitoring's Umami) usually needs no consent.
Rules and links
- TDDDG § 25
- ePrivacy 2002/58/EC, art. 5(3)
- GDPR art. 6
- PECR (UK), ICO
- Data (Use and Access) Act 2025, s. 112 (UK)
In the app: Automatic check available on a paid plan.
Trackers load before consent
Why it matters
Google Analytics, Meta Pixel, TikTok, Hotjar and similar services receive the visitor's address and data about them as soon as they load. Without consent this is not allowed, even if they set no cookies.
How to check it yourself
Private window, F12 → Network, reload the page, do not touch the banner. Look for requests to google-analytics.com, googletagmanager.com, facebook.net, connect.facebook.net, analytics.tiktok.com, hotjar.com, clarity.ms.
How to fix
Load trackers only after consent: through a banner with blocking, or in Google Tag Manager with consent mode and a "fire after consent" trigger.
Rules and links
In the app: Automatic check available on a paid plan.
Google Fonts load from Google's servers
Why it matters
The visitor's browser contacts Google and passes on its address without consent. In 2022 a Munich court (case 3 O 17493/20) awarded damages for this, followed by a wave of demand letters across Germany.
How to check it yourself
F12 → Network, reload the page, type "fonts.g" in the filter. Requests to fonts.googleapis.com or fonts.gstatic.com are a finding.
How to fix
Download the fonts (for example with google-webfonts-helper) and serve them from your own site. WordPress has plugins for this, and many themes can do it in their settings.
Rules and links
In the app: Automatic check available on a paid plan.
YouTube, maps and videos are embedded without a click
Why it matters
An embedded YouTube or Vimeo video and a Google map load at once and pass visitor data to those services before the visitor has switched anything on.
How to check it yourself
Open pages with videos and maps in a private window. If the player or map shows straight away, without a "Load video" placeholder, it is a finding. Network shows requests to youtube.com, ytimg.com, vimeo.com, maps.googleapis.com.
How to fix
A preview placeholder that loads the player only on click (consent banners and plugins offer it). For YouTube at least use youtube-nocookie.com, but it should still not load without a click.
Rules and links
In the app: Automatic check available on a paid plan.
There is a consent banner where one is needed
Why it matters
If the site uses optional cookies, trackers or third-party services, it needs a banner that asks for consent before loading them. A site without any of that needs no banner — and that is the best option.
How to check it yourself
Open the site in a private window. Is there a banner? If not, check the items "Cookies are set before the visitor agrees" and "Trackers load before consent": if nothing was found there, no banner is needed.
How to fix
Add a consent banner that blocks before consent, or remove everything that requires consent.
Rules and links
In the app: Automatic check available on a paid plan.
"Reject" is as easy as "Accept"
Why it matters
German and UK regulators require refusing to be no harder than agreeing. A banner where "Reject" is hidden in settings or looks like a small link does not count as fair consent.
How to check it yourself
Look at the first screen of the banner: is there a "Reject" or "Necessary only" button next to "Accept", of the same look and size?
How to fix
In the banner settings, turn on the reject button on the first layer and make it as visible as "Accept".
Rules and links
In the app: Automatic check available on a paid plan.
After "Reject" trackers really do not load
Why it matters
Sometimes the reject button is there but the scripts load anyway — the banner blocks nothing. That is worse than no banner: visitors are promised one thing and get another.
How to check it yourself
Private window, F12 → Network, click "Reject" and browse the site. There should be no tracker requests and no new optional cookies.
How to fix
Check the blocking setup in the banner: tracker scripts must be loaded through it, not directly in the theme code.
Rules and links
In the app: No automatic check yet. Check it yourself.
Third-party services are matched against the policy
Why it matters
Visitors have the right to know who receives their data and in which countries. Every third-party service the site contacts must be named in the privacy policy.
How to check it yourself
F12 → Network on several pages: write down every domain except your own. Compare them with the privacy policy.
How to fix
Add the missing services to the policy (who, why, what data, which country) or remove unnecessary services from the site.
Rules and links
In the app: Manual only.
Cookie consent can be withdrawn at any time
Why it matters
Withdrawing consent must be as easy as giving it. If the banner cannot be found again once closed, the visitor cannot change their mind. Usually this is a "Cookie settings" link in the footer or a small icon in a corner.
How to check it yourself
Accept cookies in the banner, then find a way to reopen the settings: a "Cookie-Einstellungen" ("Cookie settings") link in the footer or a floating button.
How to fix
Turn on the floating button in the consent platform, or add a footer link that reopens the settings (Cookiebot, Usercentrics and Complianz provide ready-made code).
Rules and links
In the app: Automatic check available on a paid plan.
The site honours the "do not sell my data" signal (GPC)
Why it matters
Browsers and extensions can tell a site "do not sell or share my data" — the Global Privacy Control signal. In California and about a dozen other states a business covered by their data laws must honour it: not run advertising trackers and not share the data. Since 2026 California also requires the site to show that the signal was honoured.
How to check it yourself
Open the site in a browser with GPC turned on (Firefox: Settings → Privacy → "Tell websites not to sell or share my data"; or Brave, or the Privacy Badger extension). F12 → Network: do advertising trackers load (facebook.net, doubleclick.net, tiktok)? Does the site say the signal was honoured?
How to fix
Turn on GPC support in the consent platform (OneTrust, Usercentrics, Cookiebot and Osano have it) and the "Opt-Out Preference Signal Honored" display.
Rules and links
In the app: Automatic check available on a paid plan.
The chatbot says it is an AI
applies to sites with an AI chatbot
Why it matters
From 2 August 2026 people in the EU must be told they are talking to an AI rather than a person, unless it is obvious. A chatbot on the site must say so at once, not at the end of a long conversation.
How to check it yourself
Open the chat on the site. Is it clear before the first question or in the first answer that an AI replies (an "AI assistant" label, an icon with an explanation)?
How to fix
Put "I am an AI assistant" in the chat window title and the first message — Intercom, Tidio, Crisp and similar tools have it in the greeting settings.
Rules and links
In the app: Automatic check available on a paid plan.
Required pages and forms
Legal notice, privacy policy and how forms handle data.
A link to the Impressum is on every page
Why it matters
In Germany and Austria a commercial site must show the owner's legal notice, and the link to it must be visible from every page — usually in the footer. In Germany a missing link draws paid warning letters from competitors (Abmahnung).
How to check it yourself
Go through several pages, including the cart and forms: is there an "Impressum" (or "Imprint", "Legal notice") link in the footer?
How to fix
Add the link to the footer shared by all pages of the theme.
Rules and links
In the app: Automatic check available on a paid plan.
The Impressum has the required details
Why it matters
The law requires a name or company name, a postal address (not a PO box), an email and one more fast contact option, and for companies who represents them (managing director, board), the register number and VAT ID (USt-IdNr) if there is one.
How to check it yourself
Open the Impressum and check: name or company with legal form (GmbH, UG…), for a company — its representative (Geschäftsführer, Vorstand), full address, email, phone or contact form, Handelsregister with number, USt-IdNr.
How to fix
Add the missing details. Impressum generators offer templates; in complex cases ask a lawyer.
Rules and links
In the app: Manual only.
The Impressum has everything Austrian law requires
Why it matters
In Austria the owner of a commercial site must show: name or company, address, contact with an email address, company register number and court (Firmenbuch), VAT number (UID), supervisory authority, chamber and professional rules where they apply. A registered company must state its register number and court on the website too.
How to check it yourself
Open the Impressum and compare with the list: name or company, address, email, Firmenbuchnummer and Firmenbuchgericht, UID-Nummer, Aufsichtsbehörde, Kammer or Berufsverband and a link to the professional rules (where applicable).
How to fix
Add the missing fields to the Impressum. The Austrian Economic Chamber (WKO) provides templates.
Rules and links
In the app: Manual only.
There is an owner disclosure under the Media Act
Why it matters
In Austria almost every website is a "periodical medium", and its owner must disclose themselves (Offenlegung). A site that only presents a person or a company and does not shape public opinion needs just the name or company, line of business and address; a blog or publication also needs the ownership structure and the editorial line (Blattlinie).
How to check it yourself
Is there an "Offenlegung gemäß § 25 MedienG" section (often inside the Impressum)? For a blog or news site — are the owners and the Blattlinie stated?
How to fix
Add an "Offenlegung gemäß § 25 MedienG" section to the Impressum: name or company, line of business, address; for a blog or publication also the owners and the Blattlinie.
Rules and links
In the app: Manual only.
A seller in Switzerland names itself and gives an address and email
applies to sites that sell goods or services to consumers online
Why it matters
In Switzerland anyone selling online must clearly and fully state who they are and give a contact address with email; incomplete details are unfair competition. The same rule requires showing the order steps, letting buyers correct input errors before ordering and confirming the order by email at once. An anonymous contact form alone is not enough.
How to check it yourself
Is there an "Impressum", "Kontakt" or "Anbieter" page with the name or company, postal address and email? Is an order confirmed by email straight away?
How to fix
Publish a page with the name or company, address and email and link it from the footer; turn on the order confirmation email.
Rules and links
In the app: Manual only.
A link to the privacy policy is visible
Why it matters
If the site collects any data at all (and every server sees the visitor's address), it must explain what it does with it. The link belongs in the footer of every page and next to forms. In California CalOPPA requires it.
How to check it yourself
Is there a "Privacy policy" ("Datenschutz") link in the footer and next to every form?
How to fix
Add the link to the footer and under the button of every form.
Rules and links
In the app: Automatic check available on a paid plan.
The policy names the services the site uses
Why it matters
A policy that leaves out Google Maps while the site shows a map does not do its job. Visitors must learn from it about everyone who receives their data.
How to check it yourself
Take the list of third-party domains (the "Third-party services" item) and look for each service in the policy text.
How to fix
Add the missing sections. An AI can draft them, but show the final text to a lawyer.
Rules and links
In the app: Manual only.
The privacy policy names the countries data goes to
Why it matters
The Swiss data protection act (since 1 September 2023) requires telling people who collects their data, why and to whom it is passed, and if data leaves the country — to which countries and on what basis (for example, standard contractual clauses). Analytics, newsletters or hosting in the US already count as a transfer abroad.
How to check it yourself
Does the privacy policy have a section on transfers abroad listing the countries and the basis for the transfer? Compare it with the services the site uses.
How to fix
Add a transfers-abroad section to the policy: the countries (for example, the US, the EU) and the basis — an adequacy decision or standard contractual clauses.
Rules and links
In the app: Manual only.
Forms send data over HTTPS only
applies to sites with forms
Why it matters
A form that submits over http sends names, emails and passwords in plain text — anyone along the way can read them.
How to check it yourself
Open the pages with forms over https. In the form code (F12 → Elements) look at the action attribute: it must not start with http://. In the Network tab, submitting must not produce requests to http://.
How to fix
Change the submit address to https and redirect the whole site to https.
Rules and links
In the app: Automatic check available on a paid plan.
Newsletter sign-up has consent and confirmation
applies to sites with a newsletter sign-up
Why it matters
You may email only people who clearly agreed. In Germany double opt-in is the practice: an email with a "confirm subscription" link. A pre-ticked box is not consent.
How to check it yourself
Subscribe with a test address. The consent box must not be pre-ticked, and a confirmation email must arrive after signing up.
How to fix
Turn on double opt-in in your mailing service (all major ones have it) and remove the pre-ticked box.
Rules and links
In the app: Manual only.
There is a "Withdraw from contract" button
applies to sites that sell goods or services to consumers online
Why it matters
From 19 June 2026 a shop in the EU that concludes contracts through its site must give the buyer a button to withdraw — as simple as the order button. In Germany the label is set by law: "Vertrag widerrufen", and the next step is "Widerruf bestätigen". The button stays available for the whole withdrawal period, and the buyer immediately gets a confirmation by email.
How to check it yourself
Look on the site — usually in the footer or the customer account — for a "Vertrag widerrufen" ("Withdraw from contract") button or link. Try it with a test order: does a form open, is there a second "Widerruf bestätigen" step, does a confirmation email arrive?
How to fix
Add the button to the footer of every page and to the customer account: a form with name, order number and email, then a confirmation step, then an email. Shopware, Shopify and WooCommerce have ready-made modules.
Rules and links
In the app: Automatic check available on a paid plan.
There are withdrawal terms and a model form
applies to sites that sell goods or services to consumers online
Why it matters
A buyer in the EU may withdraw from an online purchase within 14 days, and the shop must tell them so before the order: the period, how to withdraw, who pays for the return — and provide a model withdrawal form. Without this the withdrawal period extends to a year and 14 days.
How to check it yourself
Is there a "Widerrufsbelehrung" ("Right of withdrawal", "Cancellation policy") page, linked from the footer and from the checkout? Does it include a model withdrawal form?
How to fix
Publish withdrawal terms following the statutory model (in Germany, Annex 1 to Article 246a EGBGB) and the model form (Annex 2), and link them from the footer and the checkout.
Rules and links
In the app: Automatic check available on a paid plan.
The order button says the order is paid
applies to sites that sell goods or services to consumers online
Why it matters
In Germany the button that places an order must say unambiguously that the buyer commits to pay — "zahlungspflichtig bestellen" or something equally clear. With "Weiter" or "Bestellen" no contract is concluded, and it draws warning letters (Abmahnung).
How to check it yourself
Go through a test order to the last step. What does the button that submits the order say? Are the product, the total price and the contract term visible right above it?
How to fix
Change the label to "zahlungspflichtig bestellen" ("Order and pay") — in a shop theme this is one translation string.
Rules and links
In the app: Manual only.
Prices include VAT and shipping
applies to sites that sell goods or services to consumers online
Why it matters
In Germany consumers are shown the final price including VAT and told what shipping costs, and goods sold by weight or volume also show the price per kilogram or litre. A price "excluding VAT" for private buyers draws warning letters.
How to check it yourself
Open a few product pages and the cart. Is there "inkl. MwSt." ("incl. VAT") next to the price and a link to or amount for shipping? A unit price for goods sold by weight or volume?
How to fix
Turn on the "inkl. MwSt., zzgl. Versand" note with a link to shipping terms and the unit price display in the shop theme.
Rules and links
In the app: Manual only.
A discount shows the lowest price of the last 30 days
applies to sites that sell goods or services to consumers online
Why it matters
In the EU, when a price reduction is announced, the "was" price is the lowest price of the product in the 30 days before the reduction, not any earlier price. A struck-through "old" price that did not exist a month ago is a breach.
How to check it yourself
Find discounted products. What is shown as "was": the lowest price of the last 30 days, or just the previous one? Is it labelled?
How to fix
Show the lowest 30-day price as "was" — on major platforms this is a setting or a module; a custom shop needs a price history.
Rules and links
In the app: Manual only.
The shop says whether it takes part in consumer arbitration
applies to sites that sell goods or services to consumers online
Why it matters
In Germany a company with more than 10 people that has a website and general terms (AGB) must state on the site whether it is willing to settle disputes with consumers through an arbitration board — even if it is not. A company that has committed to take part must name the board at any size.
How to check it yourself
Is there a sentence about "Verbraucherschlichtung" in the legal notice (Impressum) or the AGB (for example, "Wir sind nicht bereit und nicht verpflichtet…")?
How to fix
Add the sentence to the Impressum and the AGB. The Chambers of Commerce (IHK) provide templates.
Rules and links
In the app: Manual only.
No outdated link to the EU dispute platform
Why it matters
The EU online dispute resolution platform (ODR) was shut down on 20 July 2025, and a link to it is no longer required. The link itself is not a breach, but it leads nowhere and shows that the legal texts have not been updated for a long time.
How to check it yourself
Search the site, especially the Impressum and the terms, for a link to ec.europa.eu/consumers/odr or the words "OS-Plattform", "Online-Streitbeilegung", "ODR platform".
How to fix
Remove the link and the sentence from the Impressum, terms and footer. If a signed cease-and-desist declaration (Unterlassungserklärung) promised to keep it, ask a lawyer first.
Rules and links
In the app: Automatic check available on a paid plan.
The site says how reviews are checked
applies to sites where visitors post their own content: comments, reviews, a forum, listings
Why it matters
In the EU, if a site shows customer reviews, it must say whether and how it checks that they come from real customers. Bought or invented reviews are banned outright.
How to check it yourself
Is there, next to the reviews or on a separate page, a note on how reviews are checked (for example, "only after a purchase") or that they are not?
How to fix
Add a sentence or two under the reviews: whether they are checked and how.
Rules and links
In the app: Manual only.
Posts can be reported and the site can be contacted
applies to sites where visitors post their own content: comments, reviews, a forum, listings
Why it matters
In the EU a site where visitors post their own content (comments, reviews, a forum, listings) must give a single point of contact for users and authorities, describe the posting rules in its terms and offer a way to report illegal content. Some duties do not apply to very small companies, but the contact and the way to report apply to everyone.
How to check it yourself
Is there a contact for questions about posts (email or form), posting rules in the terms, and a "Report" button or form on posts?
How to fix
Put the contact in the Impressum or on the contact page, add posting rules to the terms, add a "Report" button — forums and comment systems usually have a module for it.
Rules and links
In the app: Manual only.
There is a "Do Not Sell or Share My Personal Information" link
Why it matters
In California a business covered by the data law (CCPA — revenue above roughly $26 million a year, or data on more than 100,000 residents, or half its revenue from selling data) that sells data or shares it for advertising must put an opt-out link on the home page. A small site is usually not covered — then mark the item "not applicable".
How to check it yourself
Is there a "Do Not Sell or Share My Personal Information" or "Your Privacy Choices" link in the home page footer, and does it lead to an opt-out form?
How to fix
Add the link to the footer and an opt-out form or a button in the consent platform — major consent platforms have a ready-made US setting.
Rules and links
In the app: Automatic check available on a paid plan.
Newsletter emails have an unsubscribe link and the sender's address
applies to sites with a newsletter sign-up
Why it matters
In the US the CAN-SPAM Act requires every commercial email to have a clear unsubscribe link (honoured within 10 business days), the sender's real postal address and an honest subject line. Penalties are per email.
How to check it yourself
Open any newsletter email: is there an unsubscribe link and the company's postal address? Does unsubscribing work without logging in?
How to fix
Add an unsubscribe link and a postal address to the email template — every mailing service has footer fields for them.
Rules and links
In the app: Manual only.
Accessibility
Whether people with poor sight, without a mouse or with a screen reader can use the site. Automatic checks find only part of the problems. In the EU, since 28 June 2025, it is a duty for online shops and consumer services, except micro-enterprises.
Text has enough contrast
applies to sites that sell goods or services to consumers online
Why it matters
Light grey text on white cannot be read by people with poor sight, and in sunlight by almost anyone. In the EU this is a legal requirement for online shops and online services since June 2025.
How to check it yourself
The Performance screen shows the PageSpeed accessibility score. By hand — PageSpeed Insights (pagespeed.web.dev), Accessibility section, the contrast item.
How to fix
Darken the text or lighten the background to a contrast of at least 4.5:1 (3:1 for large text). Any contrast calculator can check it.
Rules and links
In the app: Checked by the app, free.
Images have a description (alt)
applies to sites that sell goods or services to consumers online
Why it matters
A screen reader reads the image description aloud to a blind visitor. Without it a product photo is an empty space and an image button is a "button without a name".
How to check it yourself
The Performance screen (PageSpeed accessibility) or PageSpeed Insights — the "Image elements do not have alt attributes" item.
How to fix
Fill in alt for meaningful images. For purely decorative ones use an empty alt="".
Rules and links
In the app: Checked by the app, free.
Form fields have labels
applies to sites that sell goods or services to consumers online
Why it matters
A field with only grey placeholder text inside is not announced by a screen reader, and the placeholder disappears as soon as the person starts typing.
How to check it yourself
The Performance screen or PageSpeed Insights — the item about form field labels.
How to fix
Give every field a visible label linked to it.
Rules and links
In the app: Checked by the app, free.
Page language and heading order are set
applies to sites that sell goods or services to consumers online
Why it matters
The lang attribute tells the screen reader how to pronounce text, and headings let a blind person move around the page the way a sighted person glances over it.
How to check it yourself
The Performance screen or PageSpeed Insights — the items about the lang attribute and heading order.
How to fix
Set <html lang="…"> and keep headings in order: one H1, H2 under it, H3 under those.
Rules and links
In the app: Checked by the app, free.
The site works without a mouse
applies to sites that sell goods or services to consumers online
Why it matters
Many people do not use a mouse. If the Buy button cannot be reached with the Tab key, or the current focus is not visible, they cannot buy.
How to check it yourself
Open the site and go through it with Tab: menu, links, form, cart, checkout. Focus must always be visible, and Enter must press buttons.
How to fix
Bring back the visible focus outline (styles often remove it with outline: none) and make real buttons out of blocks that only have a click handler.
Rules and links
In the app: Manual only.
There is an accessibility statement
applies to sites that sell goods or services to consumers online
Why it matters
In the EU, since 28 June 2025, online shops and consumer online services must describe how accessible their site is and where to report problems. In Germany the BFSG requires it. Micro-enterprises providing services are exempt: fewer than 10 people and no more than €2 million annual turnover or balance sheet total.
How to check it yourself
Look for an "Erklärung zur Barrierefreiheit" ("Accessibility statement") page, usually in the footer.
How to fix
Publish a statement: what is accessible, what is not, a contact for complaints. EU national authorities provide templates.
Rules and links
In the app: Automatic check available on a paid plan.
Site security
What any visitor can see about the site from outside: encryption, headers, unnecessary details.
Old TLS versions are switched off
Why it matters
TLS 1.0 and 1.1 are officially deprecated and considered insecure. A server that still accepts them can, in the wrong circumstances, let someone read visitor data.
How to check it yourself
Test the domain at ssllabs.com/ssltest: under Protocols, TLS 1.0 and 1.1 must say No. From a terminal: openssl s_client -connect your-domain:443 -tls1_1 -cipher 'DEFAULT@SECLEVEL=0' must fail. Without -cipher a recent OpenSSL refuses old versions on its own, and the command fails even against an old server.
How to fix
In the web server settings keep only TLS 1.2 and 1.3 (in nginx: ssl_protocols TLSv1.2 TLSv1.3;). Caddy does this by default.
Rules and links
In the app: Automatic check available on a paid plan.
http redirects to https, HSTS is set
Why it matters
If the site opens over http, the visitor's first request goes out unprotected. A redirect plus the Strict-Transport-Security header make the browser use https only.
How to check it yourself
From a terminal: curl -I http://your-domain — a 301 (or 308) to https. curl -I https://your-domain — a Strict-Transport-Security line is present.
How to fix
Turn on the https redirect in the web server and add Strict-Transport-Security: max-age=31536000. Use includeSubDomains only if every subdomain has https.
Rules and links
In the app: Automatic check available on a paid plan.
Security headers are present
Why it matters
Content-Security-Policy, X-Content-Type-Options, Referrer-Policy and forbidding the site inside someone else's frame close whole classes of attacks — content injection and clickjacking.
How to check it yourself
Test the domain at securityheaders.com or with curl -I https://your-domain.
How to fix
Add the headers in the web server: X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, frame-ancestors in CSP (or X-Frame-Options: SAMEORIGIN). Introduce CSP carefully — it can break the site.
Rules and links
In the app: Automatic check available on a paid plan.
The site does not reveal software versions
Why it matters
A "Server: nginx/1.18.0" or "X-Powered-By: PHP/7.4" header hints which known vulnerabilities to try. Not a hole, but an unnecessary hint.
How to check it yourself
curl -I https://your-domain: the Server and X-Powered-By lines must have no version numbers. In the page source — a meta generator tag with the WordPress version.
How to fix
nginx — server_tokens off; PHP — expose_php = Off; WordPress — remove the generator with a security plugin or in the theme.
Rules and links
In the app: Automatic check available on a paid plan.
Service files are not open to the world
Why it matters
An open .env hands out database passwords and service keys, an open .git the whole site code with history. This is one of the most common causes of break-ins.
How to check it yourself
Security screen → Check the server checks .env and .git of this server’s sites for free: the app requests them from your computer, like a browser, and looks at whether the site returns the file itself. The content is never shown or saved.
How to fix
Deny these paths in the web server (in nginx: location ~ /\.(env|git) { deny all; }) and change every password and key if the file was exposed.
Rules and links
In the app: Checked by the app, free.
CMS and plugins are up to date
Why it matters
Most break-ins into WordPress and other CMSs go through known vulnerabilities in old versions of the core, themes and plugins.
How to check it yourself
In the CMS admin, see whether there are updates for the core, themes and plugins. The plugin list can be checked against wpscan.com or patchstack.com.
How to fix
Update everything, delete unused plugins and themes, turn on automatic security updates.
Rules and links
In the app: No automatic check yet. Check it yourself.
The domain has SPF, DKIM and DMARC
Why it matters
Without these records anyone can send email in your domain's name, and your real emails end up in spam more often.
How to check it yourself
Test the domain at mxtoolbox.com or with dig TXT your-domain (SPF) and dig TXT _dmarc.your-domain (DMARC). DKIM is set up with your mail service.
How to fix
Add the records following your mail service's instructions. If the domain sends no email at all — SPF "v=spf1 -all" and DMARC "p=reject".
Rules and links
In the app: Automatic check available on a paid plan.
There is a security.txt
Why it matters
The /.well-known/security.txt file says where to report a vulnerability. Without it, someone who finds a hole does not know whom to tell.
How to check it yourself
Open https://your-domain/.well-known/security.txt.
How to fix
Publish the file with Contact: and Expires: fields (template at securitytxt.org).
Rules and links
In the app: Automatic check available on a paid plan.
https pages load nothing over http
Why it matters
An image, script or form over http on an https page breaks encryption: the browser blocks some of it or shows "not secure", and what gets through can be tampered with on the way.
How to check it yourself
F12 → Console: are there "Mixed Content" warnings? In the Network tab — addresses starting with http://?
How to fix
Replace http:// with https:// in the site's theme and database (WordPress has search-and-replace plugins) and add the header Content-Security-Policy: upgrade-insecure-requests.
Rules and links
In the app: Automatic check available on a paid plan.
The site's cookies carry the Secure and HttpOnly flags
Why it matters
A cookie without the Secure flag can travel over an unencrypted connection, and a login cookie without HttpOnly can be read by any script on the page. This is not a separate law but what data protection law calls "appropriate security measures".
How to check it yourself
F12 → Application → Cookies: do your domain's cookies have Secure ticked, and login (session) cookies HttpOnly? Is there SameSite=None without Secure?
How to fix
Turn on the flags in the session settings (PHP: session.cookie_secure and session.cookie_httponly; in frameworks — the session config) and wherever the site sets its own cookies.
Rules and links
In the app: Automatic check available on a paid plan.
Scripts on the payment page are listed and controlled
applies to sites where card details are entered without leaving the site (own form or the payment provider's embedded frame)
Why it matters
If card details are typed on your site's page, any third-party script on it can steal them — this is how Magecart-style attacks work. Since 31 March 2025 the card industry standard PCI DSS requires knowing every script on the payment page, justifying each and detecting changes. With a redirect to a Stripe, PayPal or bank page this is usually not your concern. If the card fields sit on your page in the payment provider's embedded frame (Stripe Elements, for example), the card never reaches you, but a script on the page can swap that frame — so the page is still kept clean.
How to check it yourself
Open the payment page, F12 → Network → filter "JS". List all scripts: whose is each one and why is it here? Are there analytics, chat or widgets that have no business on this page?
How to fix
Remove everything unnecessary from the payment page, restrict scripts with a Content-Security-Policy header and keep a list of those that remain. Simplest of all — move payment to the provider's page; the provider's embedded frame also takes away most of the worry, but the page around it must stay clean.
Rules and links
In the app: Automatic check available on a paid plan.
Server security
How the VPS itself is protected. This is not visible from outside — it is checked over SSH.
SSH login is not by password and not as root
Why it matters
Bots guess SSH passwords around the clock. Key-only login and no root login close the most common way into a server.
How to check it yourself
Security screen → Check the server looks at the SSH settings for free, read-only.
How to fix
Set up key login for a regular user with sudo, then in sshd_config: PasswordAuthentication no, PermitRootLogin no. Keep the current session open until key login works in a new one. If vpsFocus logs in to the server as root or with a password, it will lose access after this change. So first give the new user passwordless sudo, then in vpsFocus: Setup & install → Remove server → Remove from the app (monitoring on the server keeps running) and add the server again — with key login as that user.
Rules and links
In the app: Checked by the app, free.
The firewall is on
Why it matters
Without a firewall everything that happens to listen on a port faces the internet: a database, a control panel, a test server.
How to check it yourself
Security screen → Check the server.
How to fix
First allow SSH (sudo ufw allow OpenSSH), or the firewall will lock you out too, then 80 and 443, and only then turn it on: sudo ufw enable. With firewalld — the same through firewall-cmd. Remember: ports published by Docker bypass ufw.
Rules and links
In the app: Checked by the app, free.
The database and service software do not listen on the internet
Why it matters
MySQL, PostgreSQL, Redis or the Docker API reachable from outside are a direct way to the data and the server.
How to check it yourself
Security screen → Check the server shows what listens on all addresses and the Docker ports.
How to fix
Bind services to 127.0.0.1 or close the ports in the firewall; in Docker publish a port as 127.0.0.1:5432:5432.
Rules and links
In the app: Checked by the app, free.
Security updates are installed
Why it matters
Known vulnerabilities in the system and software are fixed by updates. A server without them is an open door with a sign on it.
How to check it yourself
Security screen → Check the server counts pending updates and says whether a reboot is needed.
How to fix
Install the updates (sudo apt upgrade) and turn on automatic security updates (unattended-upgrades).
Rules and links
In the app: Checked by the app, free.
There is protection against password guessing
Why it matters
fail2ban and similar tools block addresses that keep getting the password wrong, and take the bot load off the server.
How to check it yourself
Security screen → Check the server shows failed logins for the day and whether protection is running.
How to fix
Install fail2ban (sudo apt install fail2ban) — it protects SSH by default.
Rules and links
In the app: Checked by the app, free.
Site backups exist and are recent
Why it matters
Without a backup the site cannot be brought back after a break-in, a disk failure or a bad update. Data protection law requires being able to restore data. The Backups screen backs up the monitoring, not your site.
How to check it yourself
Find out where the site's backups are (at the host, in a panel, by a script) and look at the date of the latest. A backup older than a week is a reason to look closer. Try restoring one to a test location at least once. Easier — enter the backup folder in the site profile above: then Security → Check server shows the age of the newest backup itself.
How to fix
Set up daily backups of files and the database to separate storage, not to the same server.
Rules and links
In the app: Checked by the app, free.
Logs with visitor addresses are not kept forever
Why it matters
An IP address is personal data and may be kept no longer than needed. Three years of web server logs are an unnecessary risk and a question from regulators.
How to check it yourself
Security screen → Check the server reads the logrotate settings for free and shows how long logs are kept. By hand — /etc/logrotate.d/nginx (the rotate line) and the oldest file in /var/log/nginx/.
How to fix
Set a period in logrotate, for example rotate 14 with daily — two weeks, and state it in the privacy policy.
Rules and links
In the app: Checked by the app, free.
Server time is synchronised
Why it matters
Wrong time breaks certificate checks, scrambles logs when investigating an incident and confuses backup dates.
How to check it yourself
Security screen → Check the server sees for free whether the clock is synchronised. By hand — the timedatectl command: the line System clock synchronized: yes.
How to fix
Turn on synchronisation: sudo timedatectl set-ntp true.
Rules and links
In the app: Checked by the app, free.
Docker containers have no extra privileges
Why it matters
A container in privileged mode or with the Docker socket mounted is effectively root on the server: breaking into the site inside it means breaking into the whole server.
How to check it yourself
Security screen → Check the server shows for free which containers run privileged or have the Docker socket mounted. By hand — the command docker ps -q | xargs docker inspect | grep -E '"Name"|Privileged|docker.sock': every container must have Privileged false, and docker.sock must not appear among the volumes.
How to fix
Remove privileged: true and the /var/run/docker.sock mount where they are not needed; grant only the needed rights with cap_add.
Rules and links
In the app: Checked by the app, free.
In the vpsFocus app
The app has the same checklist for free and without an account: country and topic tags, a site profile, "done" marks with a progress bar shared by the team, and an AI-assistant prompt for each item or for all of them. Server and accessibility items are checked by the app itself — over SSH and through PageSpeed.
Only the check from the vpsFocus server is paid: the site is opened from outside, like a visitor sees it, with plain requests and a browser that clicks nothing in the consent banner. It finds cookies and trackers before consent, Google Fonts, embedded videos and maps, the banner and its reject button, as well as TLS, headers, SPF and DMARC. It does not probe the site's service files.