02 / What it looks at
Every check, in plain English.
Deckproof runs 112 checks: three graded areas, plus eight manufacturer signals that are not graded. The 57 that decide most grades are listed here. Security and quality are graded. EU legal items are neutral technical findings with general sources, never a verdict on your site. Every ID here is the same ID you see in your report.
SECURITY27 checksCan strangers get at your data, your keys or your code? These are the problems behind the big vibe-coding breaches.
A-01CRITICAL
Anyone can read your database
Your Supabase table answers to anyone who asks, no login needed. That is your users' data, readable by strangers. We ask once for a count only, never for a row, and report what came back. OWASP A01:2025
A-04CRITICAL
Your Firebase database is open
Your Firebase data can be read without logging in. OWASP A01:2025
S-01CRITICAL
Your master key is inside the page
The Supabase service key sits in your site's code. Whoever reads it owns your whole database, every lock ignored. CWE-798
S-02CRITICAL
A secret key is in your page
We look through your site's code for keys (Stripe, OpenAI, AWS, GitHub) that should never be public. With them, someone can spend your money or read your data. CWE-798
S-04CRITICAL
Your settings file is downloadable
The .env file, with passwords and keys, is served like any other page. CWE-538
DE-SEC-01CRITICAL
No padlock
Not served over HTTPS, or the certificate is expired or untrusted. Fix this first, everything else waits. GDPR Art. 32
S-05HIGH
Your code history is public
The .git folder is reachable, so your entire source code, past versions included, can be downloaded. CWE-538
A-05HIGH
Your file storage is listable
Supabase Storage answers an anonymous request for its bucket list, and lets a stranger list the files inside. Public buckets serve every file to anyone with the link. CWE-284
S-03HIGH
Server-only variable names in the page
Your build tool copies every VITE_ or NEXT_PUBLIC_ variable into the page. When one is called SERVICE_ROLE or SECRET, its value is public too. CWE-798
A-03HIGH
Personal data is publicly readable
A readable table contains fields like email, phone or password hashes. That is the kind of leak that gets reported to the authorities. CWE-359
C-02HIGH
Other sites can read your logged-in data
A sharing setting (CORS) echoes any origin and allows credentials, so any website can ask your backend for a visitor's data while they are logged in. A plain "*" for public data is fine and is not reported. CWE-942
AI-01HIGH
AI SDK set to run in the browser
The code turns on dangerouslyAllowBrowser, which only works with the model key in the page. Anyone reading the page can spend on your account. We never try the key. CWE-798
S-06MEDIUM
Your source code ships with the site
Source maps let anyone read your code, comments and internal links. CWE-540
A-06MEDIUM
Your database hands out its own map
The Supabase GraphQL endpoint answers an anonymous introspection query and lists every table and column. We use the answer to test the tables it names, read-only. CWE-200
S-08MEDIUM
Your API description is public
An openapi.json or swagger.json lists every route and parameter of your backend for anyone to read. CWE-200
C-04MEDIUM
Your API hands out its own map
GraphQL introspection is on, so anyone can ask your API to list everything it can do. CWE-200
T-02MEDIUM
No Content-Security-Policy
A setting that stops injected scripts. Without it a bad script can run as if it were your page. CWE-693
T-02dMEDIUM
Your Content-Security-Policy says nothing about scripts
You send a CSP, but it sets no script rule at all. Against an injected script it protects you exactly as much as having no CSP, so it counts the same. CWE-693
T-01MEDIUM
Secure connection not enforced
Browsers are not told to always use HTTPS, so a first visit can be intercepted. CWE-319
T-03MEDIUM
Your page can be framed
Another site can wrap your login page inside theirs and trick your users into clicking. CWE-1021
T-08MEDIUM
Session cookie without safety flags
A cookie that looks like a login or session token is missing the flags that keep it off plain connections and away from scripts. Analytics cookies are reported separately as low. CWE-1004
AI-02MEDIUM
Browser calls a model API directly
The page calls OpenAI, Anthropic or Google models straight from the browser. That needs a key in the page, which is public. If it goes through your own proxy, this is a false alarm. We never call the endpoint. CWE-201
A-07LOW
Accounts without email confirmation
Sign-up is open and "confirm email" is off, so a script can create thousands of accounts, including with other people's addresses. CWE-287
T-09LOW
No Permissions-Policy
Camera, microphone, location and payment stay switched on for your pages and everything embedded in them. CWE-16
T-10LOW
Security header sent twice with different values
Your app and the proxy or CDN in front of it both set the same protection header and disagree about it. Browsers do not merge the two, each picks one, so what protects your visitors is not what you configured. RFC 9110
MAIL-01LOW
No DMARC: your domain can be spoofed
Your domain publishes no DMARC policy, so mail servers have no instruction to reject mail that forges your address as the sender. That is what enables phishing in your name. DNS read only. RFC 7489
MAIL-02LOW
No SPF record
Your domain lists no allowed mail servers (SPF). With neither SPF nor DMARC, forging your domain as a sender is trivial. DNS read only. RFC 7208
EU LEGAL INFORMATION19 checksDoes your site show what EU and German law expect: Impressum, privacy notice, cookie behaviour, fonts. Reported as neutral information with sources, never as legal advice.
DE-IMP-01HIGH
No Impressum found
German law expects a provider page on commercial sites (§5 DDG). We say what we found and link the rule. General information, not legal advice. §5 DDG
DE-PRIV-01HIGH
No privacy notice found
EU law expects one (Art. 13 GDPR). We look for a linked page under the usual names. General information, not legal advice. Art. 13 DSGVO
DE-PRIV-04HIGH
Your privacy notice does not mention services you use
We compare the outside services your site actually loads (analytics, fonts, maps) with what your privacy notice names. Art. 13 DSGVO
DE-CK-03HIGH
Tracking before consent
In a real browser, on a fresh visit, we watch which analytics or ad services send data and which cookies are written before anyone clicks, and again after clicking "reject" on the banner. A tag that merely loads with Consent Mode set to denied is told apart from a pixel that fires. Without the browser pass: trackers in the code with no consent tool. General information (§25 TDDDG). §25 TDDDG
DE-IMP-04MEDIUM
Impressum is empty until JavaScript runs
The Impressum page exists, but the server sends it almost empty and the details only appear once JavaScript has run. With JavaScript off, in an archive, or to an automated check the page reads as blank. General information, not legal advice. §5 DDG
DE-PRIV-05MEDIUM
Privacy policy text is not in the page the server sends
The privacy page exists, but the server sends the frame without the policy text in it: it appears only after JavaScript runs, so we cannot read it and neither can a visitor with JavaScript off. We say so instead of guessing what it contains. General information, not legal advice. Art. 12 DSGVO
DE-3P-01MEDIUM
Fonts loaded from Google
Every visitor's address is sent to Google on each visit; often flagged since a 2022 Munich court ruling. Confirmed in a real browser when the deep scan runs. General information. LG München I
DE-3P-03MEDIUM
Embeds that phone home without consent
YouTube, Google Maps or social embeds load third-party code and set cookies on page load. We check for them when no consent tool is present. §25 TDDDG
DE-A11Y-01MEDIUM
No accessibility statement
If you sell online, German law (BFSG) expects an accessibility statement. We check whether one is linked. General information. §14 BFSG
DE-A11Y-02MEDIUM
Text below the required contrast
We measure every piece of text against the colour actually painted behind it. WCAG asks for 4.5:1 on normal text, 3:1 on large text. Needs a real browser, so it runs in the deep scan. General information. WCAG 1.4.3 / BFSG
DE-A11Y-03MEDIUM
Buttons or links without a name
An icon button with no label is announced as "button" and nothing else. We check every control for a name a screen reader can read. General information. WCAG 4.1.2 / BFSG
DE-A11Y-04MEDIUM
Form fields without a label
A placeholder is not a label: it vanishes as soon as someone types. We check whether every field has a label that assistive technology can use. General information. WCAG 3.3.2 / BFSG
DE-A11Y-05MEDIUM
Keyboard focus invisible, or no way past the navigation
We tab through the first controls and check whether anything visibly changes, and whether there is a skip link or a landmark structure to jump past the menu. General information. WCAG 2.4.7 / 2.4.1 / BFSG
US-OPT-01MEDIUM
No US opt-out link
If US ad-tech is present, California law expects a "Do Not Sell / Your Privacy Choices" link. We check whether one exists. CCPA
DE-SHOP-01MEDIUM
Shop signals, but consumer-contract basics not found
When we see a checkout, we look for the things a German consumer shop needs: an AGB page, a Widerrufsbelehrung, prices marked "inkl. MwSt.", and a "zahlungspflichtig bestellen" button. We report only what was not detected. General information. §312j BGB / PAngV
DE-A11Y-06LOW
Other machine-detectable accessibility failures
Everything else axe-core finds against WCAG 2.1 AA, reported as one row with the rule names so the report stays readable. General information. WCAG 2.1 AA / BFSG
DE-SHOP-02LOW
Subscription, but no cancellation button
If the page sells an ongoing contract, German law (§312k BGB) expects a clearly labelled cancellation button. We check for one. General information. §312k BGB
AI-ACT-01LOW
Chatbot without an "you are talking to AI" notice
If a chat or AI assistant is embedded, the EU AI Act (Art. 50, since 02.08.2026) expects visitors to be told they are interacting with AI where it is not obvious. We check for a notice. General information. Art. 50 EU AI Act
DE-HOST-01SIGNAL
Where the site is hosted
We resolve the address and look up the internet registry to report the host, its country, and whether that is inside the EU. For a visitor in the EU, hosting outside it is a third-country transfer your privacy policy should name. A fact, not a verdict, and it costs no points. Art. 44 DSGVO
QUALITY11 checksDoes your site work for Google, phones and people with screen readers.
Q-01HIGH
Search engines are told to stay away
A noindex tag or header, or a robots.txt that blocks everything, is still on. Preview builds ship with it; a launched site with it is invisible. SEO
Q-05cMEDIUM
Title is still the template default
The tab reads "Vite + React" or "Lovable App". That is the headline of your search result. SEO
Q-12MEDIUM
Localhost addresses in the shipped code
The code still calls an address that only exists on the developer's machine, so a feature silently fails for every visitor. Reliability
Q-05aMEDIUM
Missing page title or description
Search results and browser tabs show the bare address instead of your name. SEO
Q-09MEDIUM
Google sees an empty page
Your site only appears after code runs in the browser, so search engines and link previews see nothing. SEO
Q-10cMEDIUM
Images without descriptions
Screen readers and Google cannot tell what your images show. An accessibility basic (WCAG). WCAG 1.1.1
Q-13MEDIUM
Too much JavaScript
More than a couple of megabytes of script on first load takes seconds to parse on a phone. We weigh what the page really downloads. Web performance
Q-16LOW
A file could not be checked
Our own request for robots.txt, sitemap.xml or the favicon got no answer, so we say that instead of claiming the file is missing. Costs no points. Scan coverage
Q-10aLOW
No language set
Your page does not say which language it is in, which confuses screen readers and translators. WCAG 3.1.1
Q-10dLOW
The page says it is in the wrong language
The page declares one language and is written in another, so a screen reader reads it with the wrong pronunciation. Builders trained on English keep lang="en" even when you ask for another language. WCAG 3.1.1
Q-07LOW
No robots.txt or sitemap
Two small files that tell search engines where to look. We also check for a canonical link, a favicon and an <h1>. SEO
CRA MANUFACTURER SIGNALS8 checksEight public signals related to the EU Cyber Resilience Act, reported as found or not found. No grade, no verdict. The test is on a German-language page: deckproof.dev/de/cra.
CRA-01SIGNAL
security.txt or a visible security contact
We look for /.well-known/security.txt with Contact and Expires (RFC 9116), or a visible page with a contact for security reports. Found or not found, no grade. CRA (EU) 2024/2847
CRA-02SIGNAL
Wording on reporting vulnerabilities
We look for German and English wording such as "Schwachstelle melden", "Responsible Disclosure", "Coordinated Disclosure" or "CVD", and the Policy field of a security.txt. CRA (EU) 2024/2847
CRA-03SIGNAL
Security advisories or a PSIRT page
We look for a page or feed for security advisories: "Sicherheitshinweise", "Security Advisories", "PSIRT", "CSAF". CRA (EU) 2024/2847
CRA-04SIGNAL
A stated support period
We look for wording such as "Supportdauer", "Supportzeitraum", "Sicherheitsupdates bis" or "end of support" on the pages read. CRA (EU) 2024/2847
CRA-05SIGNAL
A mention of an SBOM
We look for "SBOM", "Software Bill of Materials", "Software-Stückliste", "CycloneDX" and "SPDX". CRA (EU) 2024/2847
CRA-06SIGNAL
A mention of the EU declaration of conformity
We look for "EU-Konformitätserklärung", "Declaration of Conformity" and wording about the CE marking. CRA (EU) 2024/2847
CRA-07SIGNAL
A key or policy link for encrypted reports
We look for "PGP", "GPG" and "OpenPGP", and the Encryption and Policy fields of a security.txt. CRA (EU) 2024/2847
CRA-08SIGNAL
An Impressum with a recognisable contact path
The same Impressum check as in the main test; only the kind of contact path is reported, never names, addresses or numbers. CRA (EU) 2024/2847
Run all of these on your site now, free, no signup.