DEV Community

Cover image for How to Check Website Security: The 6 Checks Every Attacker Runs First
Slawa
Slawa

Posted on Originally published at next-levels.de

How to Check Website Security: The 6 Checks Every Attacker Runs First

Originally published on next-levels.de. The free Security Check referenced below is our own tool; the six checks are the ones it runs.

Direct answer: The fastest way to check website security is from the outside, the way an attacker does: HTTPS and certificate, security headers, cookie flags, publicly reachable files such as .git or .env, outdated libraries such as jQuery and scripts without integrity protection, plus SPF, DKIM and DMARC in DNS. You need no login, just the public address, and you see what every scanner sees.

The first attack on your website isn't an attack. It's a handful of harmless requests: a GET /, a look at the response headers and the page source, a TLS connection, a few DNS queries. Nobody breaks in, nobody tries passwords. And yet, afterwards, the other side knows more about your server than most operators know themselves.

That's division of labour. Anyone attacking websites at scale scans at scale first. Server search engines like Shodan or Censys, mass scanners like Nuclei, home-grown scripts: all of them start by reading only what a server hands out voluntarily, then sort. The most rewarding find is a version number in the source. To a scanner, jquery-1.12.4.min.js isn't a file name, it's a lookup: version in, list of known vulnerabilities out. A domain with a line like that, an expired certificate and a publicly reachable .env file lands on the shortlist. A domain whose basic configuration is in order is uninteresting at this stage, because the next candidate is easier.

You can replay that triage yourself. Our free Security Check reads your homepage, your certificate and your public DNS the way a scanner does. No exploits, no login, read-only; in your server logs you'll recognise it by the user agent nextlevels-Security-Check/1.0. Its six categories are the same six things an attacker checks first.

At a glance

  • Attackers scan before they attack. The six checks here are the part everyone can see from outside: HTTPS & TLS, security headers, cookie flags, info leaks, content & scripts, email senders.
  • If the version of jQuery, Bootstrap, AngularJS, Vue, React or WordPress is visible in the source, the check compares it against known vulnerabilities and end of support, just as a scanner does.
  • A single error such as a public .env file or missing HTTPS caps the grade at C, however good the rest is.
  • An open database or remote desktop port weighs more than any missing header. The port check shows it, separately from the score.
  • A good score means the basic configuration is right. Logins, APIs and shop logic are only covered by a penetration test.

How to check website security: six areas an attacker sees from outside

Check 1: HTTPS & TLS. Do your visitors see a browser warning?

Encryption has long been the baseline assumption. The browser punishes every deviation immediately and visibly: the page is flagged "Not secure", and an invalid certificate produces a warning page where many visitors bounce. For a shop that's not a security problem, it's a revenue problem.

From the outside, what matters most are the gaps in the encryption. If the server also answers on port 80 with content instead of a redirect, the first connection on open Wi-Fi can be diverted to a copy. If the certificate doesn't match the hostname or expires in a few days, that reveals an operations team that isn't paying attention.

If DNS has no CAA record, any certificate authority in the world may issue a certificate for your domain. Whoever fools one of them gets a valid certificate in your name, and every browser would accept it.

Certificate expiry is turning into a permanent issue. In 2025 the CA/Browser Forum decided to shorten the maximum lifetime of public TLS certificates in steps: to 200 days as of 15 March 2026, to 100 days from March 2027, to 47 days from March 2029 (schedule at DigiCert). Anyone still renewing certificates by hand won't keep that up past 2027. Automated renewal, for example via ACME, becomes mandatory.

The target configuration is unspectacular: HTTPS on all hostnames, HTTP redirects with a 301 straight to the final HTTPS address, the certificate covers www and the bare domain and renews itself. Germany's federal security agency BSI, in its TR-02102-2, prefers TLS 1.3 and recommends TLS 1.2 only until the end of 2031 and only with the cipher suites it lists; TLS 1.0 and 1.1 should be switched off. Add a one-line CAA record, such as your-domain.com. CAA 0 issue "letsencrypt.org", which specifies which certificate authority may issue at all.

What this looks like in the check

No HTTPS is an error. So is an invalid certificate or one that doesn't match the hostname. If HTTP doesn't redirect to HTTPS, that's a warning. A missing CAA record is a note. Certificate expiry has two levels: under 30 days is a warning, under 7 days an error.

Maximum lifetime of public TLS certificates: 398 days until 2026, then 200, 100 and from 2029 47 days

Check 2: Security headers. Is your site protected against injected code and clickjacking?

Security headers are instructions from your server to the browser: load this page only over HTTPS, run scripts only from these sources, don't allow embedding in third-party frames, don't guess file types. They cost nothing, every browser has understood them for years, and they're still missing in many setups. For a scanner that's the first hint that nobody with a security mindset has been through the configuration.

Six headers count, and they differ enormously in cost. Five of them take ten minutes to set and change nothing about your site. The sixth, the Content Security Policy, takes a few days. It's also the only one that can mitigate a real application vulnerability.

The quick five: Strict-Transport-Security (HSTS) tells the browser to access the domain over HTTPS only for a set period, even if someone types http://. Without HSTS the first request may happen unencrypted, and that first request is the moment a redirect on open Wi-Fi succeeds. The browsers' HSTS preload list only accepts domains with a max-age of at least one year, includeSubDomains and preload.

X-Content-Type-Options: nosniff stops the browser guessing file types and executing an uploaded file as a script. X-Frame-Options or the CSP directive frame-ancestors prevent clickjacking, the invisible embedding of your page in a third-party page where a visitor thinks they're clicking somewhere else; MDN points to frame-ancestors for more options.

Referrer-Policy limits how much of the referring URL is passed to third-party sites; strict-origin-when-cross-origin is the sensible default. Permissions-Policy switches off camera, microphone or geolocation, which a shop doesn't need anyway.

Six security headers by effort and effect, the Content Security Policy highlighted

The Content Security Policy (CSP) defines which sources scripts, styles, images and frames may be loaded from. A clean CSP defuses cross-site scripting even when the application has a vulnerability, because injected code simply isn't executed. The most common misstep is script-src 'unsafe-inline'. With it, the policy allows exactly what XSS needs and is practically useless. Many shop and CMS setups do this because plugins ship inline scripts. The fix is nonces or hashes, not switching the protection off.

A starting point for nginx that works without a rebuild and deliberately leaves the CSP in report-only mode, so you see what it would block before it does:

# Baseline security headers, nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Observe the CSP first, enforce later
add_header Content-Security-Policy-Report-Only "default-src 'self'; frame-ancestors 'self'; report-uri /csp-report" always;
Enter fullscreen mode Exit fullscreen mode

One nginx quirk that regularly causes confusion: add_header isn't inherited once a location block has its own add_header. All the headers set higher up are then suddenly missing on exactly that path. If it hits the block serving the homepage, the check sees it immediately; in the configuration file it doesn't stand out.

One header misconfiguration costs more than all missing headers combined: CORS that's too generous. If your server answers every foreign Origin with that very origin in Access-Control-Allow-Origin and also sends Access-Control-Allow-Credentials: true, any website can make requests to you from your logged-in customers' browsers and read the responses. The typical origin is a CORS error message that someone wanted gone quickly.

What this looks like in the check

What counts is what your homepage actually delivers after all redirects. If the server reflects a foreign origin and also allows credentials, the check reports a warning. HSTS passes from a lifetime of 180 days. For the CSP the check looks for typical weaknesses such as unsafe-inline, unsafe-eval and the wildcard * in default-src or script-src; it's not a full CSP analysis. X-Powered-By with a version number is a warning; without one it's only a note, like COOP, CORP, COEP, includeSubDomains and preload.

Check 3: Cookie flags. Can session cookies be stolen?

The session cookie is the key to the logged-in state. Whoever has it is you, without a password, without a two-factor code. That's why the three attributes this cookie is set with matter more than the length of your password.

Secure makes the browser send the cookie exclusively over HTTPS. Without the flag it goes over the wire in plain text on the first unencrypted request to any subpage. HttpOnly removes JavaScript's access to the cookie. If an XSS attack does succeed, the injected script at least can't read the session and phone it home, the classic goal of such an attack. SameSite controls whether the cookie is sent with requests triggered by a third-party site, and is thus the browser's defence against cross-site request forgery.

Since Chrome 80 in February 2020, Chrome and other Chromium browsers have treated cookies without a SameSite attribute as Lax by default and required Secure for SameSite=None (summary of the change). According to MDN on the Set-Cookie header, only some browsers apply that default. So "the browser takes care of it" is not a configuration. A session cookie should be set explicitly like this: Set-Cookie: session=…; Path=/; Secure; HttpOnly; SameSite=Lax.

Set-Cookie line with the flags Secure, HttpOnly and SameSite=Lax and what happens without each flag

The application's own session cookie is often set correctly. The weak spots tend to be tracking, chat and A/B-testing tools. Many of them set their cookies via JavaScript right in the browser. Such cookies can't be HttpOnly by definition and never appear in a Set-Cookie header, so this check doesn't see them either. Which of them you may set before consent at all is a topic of its own; we broke it down in the article on cookies, consent and the TDDDG.

The second trap sits in the cache. If the server sends a Set-Cookie on a response that a CDN or another shared cache is allowed to store, in the worst case the next visitor gets the cached response along with someone else's cookie. Responses that set cookies should be marked private or no-store.

What this looks like in the check

The check reads the homepage's Set-Cookie headers and checks Secure, HttpOnly and SameSite for every cookie. SameSite=None without Secure is a separate finding, and so is a cookie on a response that shared caches may store. It doesn't see cookies that are only set after login or in the checkout. You check those in your browser's developer tools, "Application" or "Storage" tab, and that's worth doing on every shop at least once per release.

Check 4: Info leaks. Are source code or credentials exposed on the web?

This category holds the attacks that need no exploit. A deployment via git pull on the web server, a vhost whose document root is the repository, and /.git/HEAD is public. Whoever finds it downloads the complete repository with freely available tools, history included. In there: database credentials, API keys, sometimes private keys.

Truffle Security measured how often that happens in 2023: of the top 1 million websites, 4,500 had a publicly reachable .git directory, among them hundreds of valid credentials, 45 percent of them AWS and GitHub credentials. One site served the private key of its TLS certificate. The same logic applies to .env files, which Laravel, Symfony, Node and Shopware projects use for configuration and secrets: if it sits in the webroot and the server isn't told to block hidden files, it answers with HTTP 200 and the database password.

Two leaks don't even need a file. A debug mode left on in production shows stack traces, configuration and sometimes environment variables: the Symfony profiler, Laravel Debugbar, a Vite dev server or a Next.js dev build on the live domain. And secret keys end up in the delivered HTML or JavaScript surprisingly easily, say a Stripe live key or an OpenAI token someone added to the frontend "just for now". Whatever is in the page source, anyone can copy.

Then there are the quieter leaks. A Server: nginx/1.18.0 or X-Powered-By: PHP/7.4 tells a scanner which known vulnerabilities to try. An active directory listing shows folder contents never meant for visitors, backups and uploads included. An open Apache status page or a forgotten phpinfo() page reveals paths, modules and versions. And the HTTP method TRACE echoes the request back, headers included; it has no business on a production server.

The fix is a few lines in any web server. For nginx:

# Block all hidden files and directories, keep .well-known reachable
location ~ /\.(?!well-known) { deny all; }
# Strip the version number from the Server header
server_tokens off;
# X-Powered-By comes from PHP itself: in php.ini set expose_php = Off
Enter fullscreen mode Exit fullscreen mode

After that, every credential that ever sat in a publicly reachable file needs rotating. Blocking alone doesn't help if the file was already fetched, and you have to assume it was.

Two files in this category are welcome. Everyone knows robots.txt. /.well-known/security.txt per RFC 9116 is the standardised place where you say where security researchers should report a vulnerability they've found; mandatory fields are Contact and Expires. Whoever has this file gets tip-offs before they turn into incidents.

What this looks like in the check

The serious findings first: a reachable /.git/HEAD, /.git/config or /.env, an open directory listing, an active debug mode and secret keys in the page source (private keys, Stripe live keys, GitHub, Slack, Anthropic and OpenAI tokens) are errors. For the sensitive files the check evaluates only the status code and content type; it never reads the content. Warnings: a Server header with a version number, a reachable /.DS_Store, an open Apache status page or phpinfo() page, and active TRACE. robots.txt is a note. A valid security.txt counts as passed; if it's missing or its content is invalid, you get a note.

Three requests to /.git/HEAD, /.git/config and /.env returning status 200 and what sits behind them

Check 5: Content & scripts. Does your page load insecure or outdated files?

Your page is only as secure as what it loads. Three things sit in the delivered HTML for anyone to read: resources included over http:// although the page runs on HTTPS, external scripts without integrity protection and, often right in the file name, the version of the libraries you use.

Mixed content is the oldest of the three problems. An image over HTTP is annoying, a script over HTTP is dangerous, because anyone sitting on the network path can swap it, and it then runs with all the rights of your page. Modern browsers now block active mixed content, which means the feature silently breaks. Either way, it's a reason to fix the include.

The second problem is trust in third-party CDNs. In June 2024 the security firm Sansec documented that over 100,000 websites embedded a script that delivered malicious code to selected visitors. The domain polyfill.io, from which they had loaded a compatibility library for years, had changed hands in February 2024, and the new owner tampered with the code. The operators of the affected sites hadn't changed a thing. They had trusted a script tag someone had added at some point.

The defence is Subresource Integrity (SRI). You specify the hash of the expected file when you include it, and the browser only runs the script if the content matches:

<script src="https://cdn.example.com/lib.min.js"
        integrity="sha384-…"
        crossorigin="anonymous"></script>
Enter fullscreen mode Exit fullscreen mode

If someone changes the file on the CDN, the hash no longer matches and the script doesn't run. SRI only works for files that aren't supposed to change, i.e. versioned libraries. For tag managers, analytics loaders or chat widgets that update themselves constantly, it doesn't apply. There, your options are to keep the number of such scripts small and restrict them to exactly those hosts in the CSP. Or you self-host the library, which is the better solution for a versioned file anyway.

Outdated libraries: the cheapest finding for a scanner

The third problem is the one mass scanners like most, because it costs them no effort. The version number sits in the path (jquery-1.12.4.min.js, bootstrap@3.3.7), in the comment at the top of the file or, for WordPress, in the generator meta tag. The rest is a database lookup. Tools like retire.js have done nothing else for years, and any attacker can automate the same lookup.

jQuery shows how widespread the problem is. According to W3Techs, jQuery runs on 64.4 percent of all websites, and of those, 17.0 percent still use version 1 and 4.2 percent version 2 (as of 27 October 2026). According to endoflife.date, neither release line gets updates any more.

Two examples. For jQuery 1.12.4, the last release of the 1.x line, OSV.dev lists four known vulnerabilities, among them the XSS vulnerability CVE-2020-11022, all rated "Moderate". For AngularJS 1.8.3, the very last AngularJS release, OSV.dev lists ten entries, two of them rated "High", for example an XSS vulnerability in the angular package. Support for AngularJS ended on 31 December 2021 according to endoflife.date on AngularJS, so there won't be an official fix.

A known vulnerability in a library doesn't automatically mean it's exploitable on your site. The jQuery XSS issues, for example, only apply when untrusted HTML from an external source passes through certain jQuery functions. For the triage that doesn't matter: the scanner only sees the version and tries anyway. The fix is updating to a maintained version. Stripping the version number from the file name only hides the problem.

Flow from the file name jquery-1.12.4.min.js via OSV.dev, endoflife.date and WordPress.org to the finding

What this looks like in the check

If the HTTPS homepage loads files over http://, that's a warning. External scripts without an integrity attribute are a note, because not every script can sensibly be protected with SRI.

Back to the line from the intro. If your homepage shows the exact version of jQuery, Bootstrap, AngularJS, Vue, React or WordPress, the check compares it against OSV.dev, endoflife.date and WordPress.org. An error is a known vulnerability rated High or Critical in OSV.dev, or a WordPress version that WordPress.org marks as "insecure". Other known vulnerabilities, a version without security updates (end of life) or an available update within the same release line (for WordPress: a version WordPress.org lists as outdated) are a warning. If no version is visible, you get a note.

By these rules AngularJS 1.8.3 is an error. jQuery 1.12.4 is only a warning, because none of its known vulnerabilities is rated High. In the score, warnings and errors count the same; only the error can cap the grade at C. For the triage it makes no difference.

Check 6: Email senders. Can someone send phishing mail in your name?

This check seems to have nothing to do with your website, and yet it's the one where the damage lands most directly on your customers. Without three DNS records, any mail server in the world can send a message with invoice@your-domain.com as the sender, and to the recipient it looks genuine. Fake invoices, changed bank details, "your account has been locked": the pattern is well known, and the domain it happens in the name of takes the reputational damage. And because the forged mails reach your customers and never you, this finding often goes unnoticed for a long time.

SPF (RFC 7208) is a TXT record listing which servers may send for your domain. DKIM (RFC 6376) cryptographically signs every outgoing mail; the public key sits in DNS under a selector. DMARC ties the two together with a policy: what should a receiver do with mail that fails SPF and DKIM? p=none means deliver and just report. Only p=quarantine or p=reject filters out forgeries.

Since May 2026, DMARC has been on the IETF standards track as a Proposed Standard with RFC 9989, replacing RFC 7489 from 2015 (status "Informational"); existing v=DMARC1 records keep working.

The big mailbox providers have turned this from nice-to-have into must-have. Since February 2024, Google and Yahoo have required bulk senders to have SPF, DKIM and at least a DMARC record with p=none. Google draws the line at more than 5,000 messages a day to Gmail addresses (Google sender guidelines) and has been ramping up enforcement since November 2025, up to rejections (Google on enforcement). Microsoft followed for Outlook.com in May 2025 and rejects non-compliant mail from high-volume senders with 550 5.7.515 Access denied (Microsoft Tech Community).

A shop with a large newsletter list can reach that threshold. And below it, the same three records still decide whether your order confirmation lands in the inbox or in spam.

Three records that establish "nobody may send in my name except my mail provider":

# SPF: only Google Workspace may send, hard-fail everything else
your-domain.com.          TXT  "v=spf1 include:_spf.google.com -all"

# DKIM: public key under the provider's selector
google._domainkey.your-domain.com.  TXT  "v=DKIM1; k=rsa; p=…"

# DMARC: forgeries to quarantine, reports to you
_dmarc.your-domain.com.   TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc@your-domain.com"
Enter fullscreen mode Exit fullscreen mode

The right order: set SPF and DKIM, create DMARC with p=none and a reporting address, read the reports for two to four weeks until every legitimate sender (shop, newsletter tool, CRM, ticketing system) authenticates cleanly, then move to quarantine and later to reject. Switch straight to reject without knowing the reports and you'll happily block your own invoicing system.

What this looks like in the check

Everything is read from your domain's public DNS. Three warnings are possible: missing SPF, missing DMARC, and DMARC with p=none. If it says p=none, you've set up DMARC but haven't stopped a single forgery yet. The check looks for DKIM under the three common selectors default, google and selector1; if your provider uses another one, that only shows up as a note. It doesn't check DNSSEC or actual delivery. If you only want to check the domain rather than the whole website, use the leaner SPF, DKIM and DMARC check.

Three DMARC levels: p=none, p=quarantine and p=reject

Extra: the port check, for your own domain only

The six checks read what your web server delivers. An attacker also looks at which other doors are open on the same address. A directly reachable database, a remote-desktop endpoint or an FTP server with plain-text passwords are targets for automated login attempts. If you run a Linux server with SSH open, you can count them yourself, for example with sudo journalctl -u ssh -u sshd --since today | grep -c "Invalid user". The number is a lower bound, because it only counts attempts with usernames that don't exist.

The port check attempts a connection on 16 common ports: web (80, 443, 8080, 8443), mail (25, 465, 587, 110, 143, 993, 995), FTP (21), SSH (22), MySQL (3306), PostgreSQL (5432) and Remote Desktop (3389). It stops at opening the connection, with a two-second timeout: no login, no request to the service.

Grid of the 16 checked ports, coloured by rating when open: passed, warning or error

The rating is strict. Open ports 80 and 443 pass; that's your website, after all. Open ports 21, 22, 3306, 5432 and 3389 are an error, any other open port a warning. Counting SSH as an error will annoy some admins. I think it's right, and the reason is called regreSSHion: in July 2024 Qualys published a vulnerability in OpenSSH (CVE-2024-6387) that allowed code execution on glibc-based Linux systems without anyone having to log in. Keys instead of passwords don't help against that, because the flaw triggers before any authentication. SSH belongs behind a VPN or an IP allowlist.

The result counts towards neither the score nor the grade and is only sent to an address on the checked domain or a parent domain, up to the registrable domain: for www.example.com, info@example.com works. With the code from that email, the ports also appear in the report.

How the check protects itself against misuse

A tool that fetches arbitrary URLs on request is a target itself. The classic pattern is server-side request forgery: someone enters an internal address such as 192.168.0.1 instead of a website and lets the scanner probe its operator's network. The craftier variant is a domain that points to a public IP when it's checked and to an internal one milliseconds later (DNS rebinding).

So the check blocks private and internal IP addresses. It resolves the name once and pins the whole scan to that IP, so a DNS answer that's changed afterwards goes nowhere. And it checks every redirect individually before following it: parse the address, resolve it, check the IP. Rate limits apply against bulk use: 8 scans per minute per visitor IP, 20 scans per hour per target domain, at most 2 parallel scans per visitor. Response size is capped at 512 KB, and every fetch has a timeout. That's plenty for a re-check after a fix, and useless for a scanning campaign across other people's domains.

Misuse protection of the check: resolve DNS once, check and pin the IP, check every redirect

What the grade means

The score is deliberately simple. Every check counts the same; there's no hidden weighting. The score is the share of passed checks among all rated ones (passed, warning or error), rounded to 0 to 100. Notes don't count. That gives the grade: A from 90 points, B from 80, C from 65, D from 50, F below that.

Then there's a second rule: a single error caps the grade at C. A worked example: 20 rated checks, 17 passed, gives 85 points and therefore a B. If one of the other three is an error, the score stays at 85 but the grade is still C. A website with perfect headers and a public .env file isn't a B website, because an attacker isn't looking for the average of your configuration but for the one spot that's enough. That's why the summary names the most urgent finding separately under "Fix first".

Result header of the Security Check for example.com: grade D, 60 out of 100 points, Fix first

What an external check can't see belongs in the findings just as much. It only checks the homepage: subpages, login areas, checkout and APIs stay out of scope. It only compares versions for the six libraries and systems above, and only if the page reveals them; shop, plugin and server versions aren't checked for vulnerabilities. And it doesn't attack anything. For shops, customer portals and anything with sensitive data, a penetration test that attacks the application itself belongs on the list as well.

Legally, the basic configuration isn't optional either. Art. 32 GDPR requires appropriate technical measures, taking into account the state of the art, and encrypted connections and a maintained server configuration are part of that. If your privacy policy mentions encryption and security measures, the check shows whether that holds for the part visible from outside.

That sets the order: basic configuration first, then the pentest. Anyone who orders a penetration test on a website with a public .git already knows the first twenty minutes of the report.

From finding to fix: three routes

Depending on who looks after your server and DNS, there are three realistic routes. If your company has its own admins or a hosting provider with access to the configuration, the report is enough: every finding comes with its recommendation, headers and redirects are a few lines, DNS records three lines, and afterwards you simply check again. If a CDN with a page cache sits in front of your site, it may briefly still serve the old response.

If you don't have an ops team of your own, we implement the fixes on web server, CDN, shop and DNS and document the result with a fresh check. Security patches and updates of outdated components are part of our maintenance and support, servers and infrastructure part of hosting and scaling. And where a shop or customer portal with real data sits behind it, we bring in a specialised partner for the penetration test, agree the scope and close the gaps found afterwards.

You see the score and grade without entering anything. Your business email address unlocks the findings and recommendations. So the first step costs you nothing but a URL: check your website, look at the score, and then you know what the other side already knows.

FAQ: website security check

Which finding is the most urgent?

Everything the check shows as an error; the summary names the first of them under "Fix first". Errors are:

  • no HTTPS, or an invalid certificate or one expiring in under 7 days
  • a publicly reachable .git directory, a reachable .env file or an open directory listing
  • an active debug mode or a secret key in the page source
  • a library with a severe known vulnerability, or a WordPress version that WordPress.org marks as insecure

For exposed files and keys, rotate every affected credential afterwards.

How can I check my website security for free?

With an external check that only reads what your server delivers to every visitor: HTTPS and certificate, security headers, cookie flags, exposed files, mixed content, visible library versions and the DNS records SPF, DKIM and DMARC. Our Security Check shows the score and grade straight away, without login and without attacking anything.

What do I get with and without an email address?

Without entering anything you immediately see the score, the grade, the number of passed checks, warnings, errors and notes, and every check point with its status; the details are locked. With your business email address and consent to the privacy policy, you unlock every check with its finding and recommendation right away, and the full report arrives by email within a few minutes. Only the email is required; first name, last name and phone are optional. Someone from our team gets in touch once, within one working day.

Can I use the Security Check on other people's websites?

Technically yes: the web check only uses publicly reachable addresses and public DNS records. The port check result, however, only goes to an email address on the checked domain, and limits per IP and per target domain make the tool unsuitable for mass scanning.

Is a website security check the same as a penetration test?

No. A penetration test deliberately attacks an application: logins, APIs, permissions, inputs. A security check grades the public configuration. The two complement each other, and the basic configuration should be right before the pentest.

How often should I check website security?

After every deployment that touches server, CDN, DNS or included libraries, and otherwise at least quarterly. Certificates now run shorter, plugins add cookies and scripts without asking, old library versions keep collecting new vulnerabilities, and DNS records change whenever a new newsletter or CRM tool is added.


Questions about one of the six checks, or a finding you can't place? Drop it in the comments.

Top comments (0)