Checks
Every check has a stable ID. Your code branches on the ID, people read the text. Existing IDs never change; at most, new ones are added. There are currently 63, of which 16 cover secret keys in an app's JavaScript files.
What a finding looks like
A finding is a place where something is missing or stands out. Every finding in the response has this shape.
{
"id": "code.secret.supabase_service_role",
"sev": "warn",
"critical": true,
"label": "Supabase master key exposed (service_role, 1×)",
"why": "With this key, any visitor can read, change and delete your entire database, bypassing all access rules. …"
}| Field | Meaning |
|---|---|
id | Stable ID from the tables below. This is what your code branches on. Missing on locked findings. |
sev | warn (warning, should be fixed) or info (notice, no rush). |
label | Short title for people. May contain details, such as the name of a cookie. |
why | One or two sentences on what the finding means. |
refs | Only on version.vulnerable: CVE or OSV identifiers, at most six. |
source | Only on version.vulnerable: where the match comes from, for example OSV.dev. |
standards | API only (/api/v1/scan): mapping to cwe, owasp (Top 10:2025), asvs (5.0), bsi (IT-Grundschutz) and law, see Mapping to standards. |
critical | Only on exposed secret keys in the JavaScript files: true. Each such finding deducts 40 points. |
locked | Only without a paid plan: true on locked findings. label is then empty, and id, why, refs and source are missing. |
The REST API writes label and why in German unless you ask for English with lang=en, see Language. The MCP server answers in English by default. Branch on id, not on the text. A finding always means "potentially affected". It proves nothing, because we only read what any visitor sees. For keys, we name the type and where it was found and show the value only shortened, for example sk_live_…9f2A. We never output the full value.
Locked finding
Without a paid plan, only 2 findings come in full. The others keep their position in the list, but only with severity and locked: true. Check locked before your code branches on id. Full reports are available with Business, see Shortened reports.
{
"sev": "info",
"label": "",
"locked": true
}Encryption and certificate
Whether your site is reachable over an encrypted connection and the certificate is valid, the padlock in the browser. If either is missing, third parties can read along or visitors see a warning page. Findings appear in findings.https and findings.tls.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
https.missing | Warning | No HTTPS The site ends up unencrypted on http. Inputs such as passwords travel across the network in readable form, and the grade is always F. | CWE-319 · OWASP A04:2025 · ASVS V12.2.1 · BSI APP.3.2, TR-03116-4 | Explainer |
https.no_redirect | Warning | No redirect from http to https The homepage answers over http:// with content instead of redirecting to https://. Anyone who opens the address that way browses unencrypted. With HSTS it is only a notice, because returning visitors are protected. | CWE-319 · OWASP A04:2025 · ASVS V4.1.2, V12.2.1 · BSI APP.3.2 | Explainer |
tls.invalid | Warning | Invalid certificate Browsers show a warning page instead of your site, for example because the certificate does not match the address. | CWE-295 · OWASP A07:2025 · ASVS V12.2.2 · BSI APP.3.2 | Explainer |
tls.expired | Warning | Certificate expired The expiry date has passed. Browsers show a warning page instead of your site. | CWE-324 · OWASP A04:2025 · ASVS V12.2.2 · BSI APP.3.2 | Explainer |
tls.expiring | Warning | Certificate expires soon A warning under 14 days, a notice under 30 days. After expiry, visitors see a warning page. | CWE-324 · OWASP A04:2025 · ASVS V12.2.2 · BSI APP.3.2 | Explainer |
tls.old_protocol | Warning | Outdated encryption Our connection used TLS 1.0 or 1.1. Both are considered insecure; the German Federal Office for Information Security (BSI) requires at least TLS 1.2. | CWE-327 · OWASP A04:2025 · ASVS V12.1.1 · BSI CON.1, TR-03116-4 | Explainer |
Browser security settings
House rules your server sends to the browser with every response, for example: do not run scripts from elsewhere. Without them, the browser also runs injected code. Findings appear in findings.headers.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
header.csp.missing | Warning | No protection against injected scripts Neither the Content-Security-Policy header nor an equivalent meta tag with script-src or default-src is set. If foreign code gets into the page, the browser runs it. | OWASP A02:2025 · ASVS V3.4.3 · BSI APP.3.1 | Explainer |
header.csp.weak | Notice | CSP barely stops injected scripts The Content-Security-Policy is set but doesn't govern scripts, allows 'unsafe-inline' without a nonce or hash, or allows scripts from any address. Rated as in Google's CSP Evaluator. It then earns 10 points instead of 25. | OWASP A02:2025 · ASVS V3.4.3 · BSI APP.3.1 | Explainer |
header.hsts.missing | Warning | Encryption not enforced permanently The Strict-Transport-Security (HSTS) header is missing or set to max-age=0. On open networks, visitors can then be redirected to an unencrypted version. | CWE-319 · OWASP A04:2025 · ASVS V3.4.1 · BSI APP.3.2 | Explainer |
header.frame.missing | Notice | Other sites may embed your site Neither X-Frame-Options nor frame-ancestors in the CSP is set. Users can be tricked into invisible clicks. | CWE-1021 · OWASP A06:2025 · ASVS V3.4.6 · BSI APP.3.1 | Explainer |
header.xcto.missing | Notice | Browsers may guess file types The X-Content-Type-Options header is missing. An uploaded file can then run as a script. | OWASP A02:2025 · ASVS V3.4.4 · BSI APP.3.1 | Explainer |
header.referrer.missing | Notice | Full addresses go to other sites The Referrer-Policy header is missing. Clicking a link can pass on the full address, including any identifiers in it. | OWASP A02:2025 · ASVS V3.4.5 · BSI APP.3.1 | Explainer |
header.permissions.missing | Notice | Camera, microphone and location not blocked The Permissions-Policy header is missing. Embedded third-party content may request these features. | OWASP A02:2025 · BSI APP.3.1 | Explainer |
header.server.version | Notice | Server reveals its version The Server header contains a version number. Anyone who knows a vulnerability in it finds the site faster. | CWE-497 · OWASP A01:2025 · ASVS V13.4.6 · BSI APP.3.2 | Explainer |
header.poweredby | Notice | Site reveals its technology The X-Powered-By header is set. It serves no purpose. | CWE-497 · OWASP A01:2025 · ASVS V13.4.6 · BSI APP.3.2 | Explainer |
Protection against spoofed email
Whether a record at your domain provider defines who may send email in your name. Without it, fake invoices with your sender address get through more easily. Findings appear in findings.email.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
email.spf.missing | Warning | Senders not defined (SPF) The domain has no TXT record with v=spf1. Mailboxes have a harder time spotting forgeries that use your sender address. | CWE-290 · OWASP A07:2025 · BSI APP.5.3 | Explainer |
email.spf.allow_all | Warning | SPF allows any sender The SPF record ends in +all. Any server may send in your name. | CWE-290 · OWASP A07:2025 · BSI APP.5.3 | Explainer |
email.dmarc.missing | Warning | No policy for spoofed email (DMARC) There is no TXT record with v=DMARC1 under _dmarc. Spoofed email in your name gets delivered. | CWE-290 · OWASP A07:2025 · BSI APP.5.3 | Explainer |
email.dmarc.none | Notice | DMARC only reports The policy p=none reports forgeries but rejects none of them. | CWE-290 · OWASP A07:2025 · BSI APP.5.3 | Explainer |
email.spf.too_many_lookups | Warning | SPF with too many DNS lookups Including nested records, the SPF record triggers more than 10 DNS lookups (RFC 7208). Many mailboxes then treat it as an error. | CWE-290 · OWASP A07:2025 · BSI APP.5.3 | Explainer |
email.transport.unprotected | Notice | No MTA-STS and no DANE The domain receives email but does not require encrypted delivery. An attacker on the network can suppress encryption between mail servers. | CWE-319 · OWASP A04:2025 · BSI APP.5.3, TR-03108 | Explainer |
Domain and DNS
Public records of your domain: whether a dangling redirect hands your address to strangers, who may issue certificates, whether DNSSEC is active and where security researchers can report vulnerabilities. Findings appear in findings.dns.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
dns.takeover | Warning | Address can be taken over The address points via CNAME to a service such as GitHub Pages, Heroku, Amazon S3 or Shopify whose target no longer exists (recognized by the service's error page). Whoever creates it there serves their own content under your address. | OWASP A02:2025 · BSI APP.3.6 | Explainer |
dns.caa.missing | Notice | No CAA record Any certificate authority may issue a certificate for the domain. | OWASP A02:2025 · BSI APP.3.6, CON.1 | Explainer |
dns.dnssec.missing | Notice | No DNSSEC The domain is not signed, so DNS answers can be forged in transit. Checked through DNS-over-HTTPS at Cloudflare. | OWASP A02:2025 · BSI APP.3.6 | Explainer |
dns.securitytxt.missing | Notice | No security.txt There is no contact address for security reports at /.well-known/security.txt (RFC 9116). | BSI DER.2.1 | Explainer |
dns.securitytxt.expired | Notice | security.txt expired The Expires date is in the past. | BSI DER.2.1 | Explainer |
Outdated software
Components of your site in versions with publicly known vulnerabilities. Findings appear in findings.versions.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
version.eol | Warning | Software without security updates The vendor no longer ships updates for this version (source: endoflife.date). New vulnerabilities stay open. | CWE-1104 · OWASP A03:2025 · ASVS V15.2.1 · BSI OPS.1.1.3 | Explainer |
version.vulnerable | Warning | Software with known vulnerabilities The detected version has entries at OSV.dev or in our own list. We report it as "potentially affected". | CWE-1395 · OWASP A03:2025 · ASVS V15.2.1 · BSI OPS.1.1.3 | Explainer |
Source code and JavaScript files
What any visitor can read in the source and JavaScript files of your app, for example keys for databases, AI services or payments. Findings appear in findings.exposure.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
code.secret_pattern | Warning | Possible key under a telltale name The HTML contains a value under a name such as client_secret, api_secret or access_token. Any visitor can copy it. We name the field and show the value only shortened, never in full. Keys with a known prefix (Stripe, AWS, OpenAI …) are reported under their own ID. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.supabase_service_role | Warning | Supabase master key exposed service_role key in the page source or JavaScript files. Anyone can use it to read, change and delete the entire database, bypassing all access rules. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1, V8.3.1 · BSI CON.10 | Explainer |
code.secret.supabase_secret_key | Warning | Secret Supabase key exposed sb_secret key in the page source or JavaScript files. Anyone can use it to access the entire database. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1, V8.3.1 · BSI CON.10 | Explainer |
code.secret.llm_key | Warning | AI key exposed Key for OpenRouter, Groq, xAI, Hugging Face, Replicate, Perplexity or ElevenLabs in the page source or JavaScript files. Anyone can use it to send requests billed to you. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.webhook_url | Warning | Webhook URL exposed Slack, Discord, Teams or Zapier webhook in the page source or JavaScript files. Anyone can use it to post messages to your channels, including fake instructions. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.llm.browser_direct | Warning | AI call made directly from the browser The app calls OpenAI or Anthropic without a server of its own. The key has to sit in the browser for that and can be read out. | CWE-798 · CWE-602 · OWASP A07:2025 · ASVS V13.3.1, V8.3.1 · BSI CON.10 | Explainer |
code.env.public_secret_name | Warning | Secret variable in public code VITE_, NEXT_PUBLIC_ or REACT_APP_ variable with SECRET, PRIVATE or PASSWORD in its name. Its value ends up in every browser. | CWE-540 · OWASP A01:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.openai | Warning | OpenAI key exposed OpenAI API key in the page source or JavaScript files. Anyone can use it to send requests billed to you. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.anthropic | Warning | Anthropic key exposed API key for Claude in the page source or JavaScript files. Anyone can use it to send requests billed to you. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.stripe | Warning | Secret Stripe key exposed sk_live or rk_live key in the page source or JavaScript files. Depending on its permissions, it can issue refunds and retrieve customer data. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.aws | Warning | AWS access key exposed AKIA or ASIA key in the page source or JavaScript files. Depending on its permissions, it reaches storage, servers and billing of your AWS account. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.github | Warning | GitHub token exposed GitHub access token in the page source or JavaScript files. Depending on its permissions, it can read or change your source code. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.slack | Warning | Slack token exposed Slack token in the page source or JavaScript files. Depending on its permissions, it can read or send messages. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.sendgrid | Warning | SendGrid key exposed Email delivery key in the page source or JavaScript files. Anyone can use it to send email through your account. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.mail_api | Warning | Email delivery key exposed Key for Resend, Brevo or Mailchimp in the page source or JavaScript files. Anyone can use it to send email through your account, for example phishing with your sender address, or to retrieve your contact lists. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.service_token | Warning | Access token for an online service exposed Token with a distinctive prefix or under a distinctive name, for example for the Supabase account, Shopify Admin, Google OAuth, Notion, Airtable, Telegram, GitLab, npm, webhook signatures (whsec_) and more than 100 other services from the gitleaks rule set, including Atlassian, Cloudflare, Datadog, Doppler, Heroku, Mailgun, Pulumi and Square. Depending on the service, it can read or change data or trigger actions in your name. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.twilio | Warning | Twilio key exposed SMS and voice key in the page source or JavaScript files. Anyone can use it to send SMS at your expense. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.database_url | Warning | Database credentials exposed Connection URL with user and password in the page source or JavaScript files. Whoever has it can log in to the database directly. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.secret.private_key | Warning | Private key exposed Private key (PEM) in the page source or JavaScript files. Whoever has it can impersonate your service. | CWE-798 · CWE-540 · OWASP A07:2025 · ASVS V13.3.1 · BSI CON.10 | Explainer |
code.supabase.rls_check | Notice | Database reachable directly from the browser Supabase with a public key (anon or sb_publishable). The data is only protected by access rules (RLS) on every table. We cannot see from the outside whether they are active. | CWE-862 · OWASP A01:2025 · ASVS V8.3.1, V8.2.2 · BSI CON.10, APP.3.1 | Explainer |
code.firebase.rules_check | Notice | Firebase reachable directly from the browser The Firebase configuration is in the source. That is intended, but the data is only protected by Security Rules in Firestore, Realtime Database and Storage. We cannot see from the outside whether they hold. | CWE-862 · OWASP A01:2025 · ASVS V8.3.1, V8.2.2 · BSI CON.10, APP.3.1 | Explainer |
code.sourcemap_bundle | Notice | Source maps in the JavaScript files Publicly served .map files that allow the original source code, including comments, to be reconstructed. We only report them when the file is actually served. | CWE-540 · OWASP A01:2025 · ASVS V13.4.7 · BSI CON.10 | Explainer |
code.public_key | Notice | Google key in the source In the HTML or JavaScript files, often intentional, for example for Maps. Firebase configurations are reported separately. Without a restriction to your domain, anyone can use it at your expense. | OWASP A02:2025 · BSI CON.10 | Explainer |
code.mixed_content | Warning | Unencrypted parts on an HTTPS page Images, scripts or stylesheets load over http. On the same network they can be swapped out. | CWE-319 · OWASP A04:2025 · ASVS V12.2.1 · BSI APP.3.1 | Explainer |
code.debug_output | Warning | Error message visible Text that looks like a technical error message, such as a stack trace or a PHP warning. It often reveals paths and versions. | CWE-209 · OWASP A10:2025 · ASVS V16.5.1, V13.4.2 · BSI APP.3.1 | Explainer |
code.sri.missing | Notice | Third-party scripts without a fingerprint (SRI) Scripts with a fixed version (for example from a CDN) without the integrity attribute. If that server is compromised, the modified code runs too. Services whose script changes all the time don't count, SRI doesn't work there. | CWE-353 · CWE-829 · OWASP A08:2025 · ASVS V3.6.1 · BSI APP.3.1 | Explainer |
code.sourcemap | Notice | Source code possibly readable (source map) The HTML references a .map file. | CWE-540 · OWASP A01:2025 · ASVS V13.4.7 · BSI CON.10 | Explainer |
code.sensitive_paths | Notice | References to sensitive files Paths such as .env, .git or backup files appear in the HTML. We do not request them. | CWE-538 · OWASP A01:2025 · ASVS V13.4.1, V13.4.7 · BSI APP.3.2 | Explainer |
Data protection (GDPR)
Common data protection mistakes that can be proven from the outside and often lead to legal warnings in Germany: Google Fonts from Google's servers, tracking before consent, embedded content and missing mandatory links. Not legal advice. Findings appear in findings.privacy.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
privacy.google_fonts | Warning | Google Fonts from Google's servers Fonts from fonts.googleapis.com or fonts.gstatic.com, found in the HTML, stylesheets or JavaScript files. A warning on German-language sites; otherwise, or if the address only appears in JavaScript, a notice. | CWE-359 · BSI CON.2 · Art. 6(1) GDPR | Explainer |
privacy.tracking_cookies | Warning | Tracking cookies before consent The server already sets analytics or advertising cookies such as _ga, _fbp or _gcl_au in its first response. | CWE-359 · BSI CON.2 · Section 25 TDDDG · Art. 6(1) GDPR | Explainer |
privacy.tracking_no_consent | Warning | Tracking without a recognizable consent tool The site loads trackers such as Google Analytics, Meta Pixel or Hotjar and we find no consent tool. Google Tag Manager alone is a notice, because it can manage consent itself. | CWE-359 · BSI CON.2 · Section 25 TDDDG · Art. 6(1) GDPR | Explainer |
privacy.third_party_embeds | Notice | Embedded content without consent YouTube, Google Maps or Vimeo sit directly in the page as an iframe and load on page view. | CWE-359 · BSI CON.2 · Section 25 TDDDG · Art. 6(1) GDPR | Explainer |
privacy.legal_links | Notice | Legal notice or privacy policy not linked The homepage of a German-language site has no such link. Only checked when the HTML itself contains links. | BSI CON.2 · Section 5 DDG · Art. 13 GDPR | Explainer |
Cookies
Whether the cookies on your site are protected against eavesdropping and third-party scripts. Findings appear in findings.cookies.
| ID | Severity | What is checked | Standards | Help |
|---|---|---|---|---|
cookie.secure.missing | Notice | Cookie without Secure A cookie whose name looks like a session or login may also be sent over unencrypted connections. | CWE-614 · OWASP A02:2025 · ASVS V3.3.1 · BSI APP.3.1 | Explainer |
cookie.httponly.missing | Notice | Cookie without HttpOnly A cookie whose name looks like a session or login is readable by scripts. Foreign code could use it to take over the account. | CWE-1004 · OWASP A02:2025 · ASVS V3.3.4 · BSI APP.3.1 | Explainer |
Mapping to standards
Every check is mapped to recognized standards, so a finding can be placed in audits, for NIS2 or for auditors. The mapping is in the table above, next to every finding in the PDF report and in the API field standards. It is our classification, not a certification.
- CWE (MITRE): the type of weakness. We only use IDs that MITRE allows for mapping. If none fits, the field stays empty.
- OWASP Top 10:2025: the category follows from the official CWE list per category. Only for checks without a CWE do we classify ourselves, then almost always A02 (Security Misconfiguration).
- OWASP ASVS 5.0.0: the requirement the finding violates, for example V3.4.1 for HSTS.
- BSI IT-Grundschutz (Compendium Edition 2023, German Federal Office for Information Security): the module, for example APP.3.1 web applications and web services, plus the technical guidelines TR-03116-4 (TLS) and TR-03108 (email transport).
- Law: for data protection, the provision, for example Section 25 TDDDG or Art. 13 GDPR. Not legal advice.
We only reference IDs and write the texts ourselves. OWASP publishes ASVS and the Top 10 under CC BY-SA 4.0, CWE comes from MITRE.
What we never do
The check stays on the surface. It loads the page and the JavaScript files the page includes itself, from the same domain only. It never does the following, no matter what the request says.
- Probe hidden paths or request files such as .env
- Load files your site does not include or fetch itself (except the public file /.well-known/security.txt), or read scripts from other domains
- Look for open ports (port scan)
- Submit forms or send attack payloads
- Log in or use keys it finds
- Show or store the full values of keys it finds
- Check internal or private addresses
More in the help article What we don't check.