What we scan for
Every check HatTest runs, straight from our detection catalog — 156 finding classes across 18 categories, each mapped to both the OWASP and CWE taxonomies and carrying the impact it has if we find it. We report what we find with evidence and a fix; we never claim a site is “secure.”
- High 66
- Medium 48
- Low 17
- Info 25
Severity shown is each check’s nominal default — the severity you see on a real finding is judged per target at scan time. Checks marked Deep scan run in the authenticated deep tier using your own two test logins; everything else runs in every standard scan.
Mapped to the OWASP Top 10
Every check carries an OWASP category and a CWE, so results slot into the taxonomy your team and your auditors already use.
- A01:2025 Broken Access Control 35
- A02:2025 Security Misconfiguration 53
- A03:2025 Software Supply Chain Failures 4
- A04:2025 Cryptographic Failures 57
- A05:2025 Injection 1
- A07:2025 Authentication Failures 3
- A08:2025 Software or Data Integrity Failures 2
- A10:2025 Mishandling of Exceptional Conditions 1
Our checks map to 8 of the OWASP Top 10. We don’t claim the rest: the remaining categories aren’t meaningfully observable from an external, unauthenticated scan (logging and monitoring failures, for example, are visible only from inside your systems). We’d rather show a shorter list we can prove than a full one we can’t.
- Access control & data exposure Access control34
- Secrets & credentials Leaked secrets & credentials43
- Exposed files & disclosure Exposed files & artifacts28 Information disclosure5 Error message disclosure1
- Transport & TLS TLS certificates7 TLS protocols1 TLS ciphers4 Transport security (HSTS)1
- Browser & web hardening Content security policy2 Session cookies3 Cross-origin (CORS)6
- Identity & email Authentication providers4 Email authentication (SPF/DMARC)7
- Supply chain, DNS & AI surface Software supply chain6 DNS & subdomain takeover1 AI & agent surface2
- Injection Injection1
Access control & data exposure
34 checks-
High
Unauthenticated GraphQL access to sensitive data
A schema-built query executed anonymously returned records containing sensitive-looking fields — the GraphQL analog of broken access control.
Why it mattersThe API serves private data to unauthenticated callers straight from the client — a direct data breach.
-
High
Authenticated user can read another user's object by ID (BOLA / IDOR)Deep scanSupabase only
A logged-in test user could not list a table's rows, yet could fetch another user's specific object directly by its id — object-level authorization is missing (the classic BOLA / IDOR shape, on a table that often exposes no owner column).
Why it mattersAny authenticated user who knows or guesses an object's id (sequential ids, ids leaked in URLs/emails/other responses) can read another user's record, even though the app never lists those rows to them. When the object carries sensitive data this is a direct horizontal data breach.
-
High
Authenticated user can read another user's sensitive rowsDeep scan
A logged-in test user that owns no rows in a table could still read another user's rows, and those rows carry sensitive data — access control is not scoped per user.
Why it mattersAny authenticated account can read other users' private data — horizontal data exposure across accounts (broken object-level authorization). This is the clean, benign-interpretation-free leak.
-
High
BaaS collection exposes sensitive data to anonymous reads
A PocketBase/Appwrite collection returned records with sensitive-looking fields to an anonymous list request.
Why it mattersThe collection's access rules allow unauthenticated reads of private data — a direct data breach.
-
High
CouchDB allows anonymous database enumeration (admin party)
An anonymous GET /_all_dbs succeeded — the CouchDB server has no admin configured ('admin party'), so every database is world-accessible.
Why it mattersWith no admin, anyone can list, read, and modify every database on the server — a catastrophic, total data compromise.
-
High
CouchDB database exposes sensitive data to anonymous reads
An anonymous read of a CouchDB database returned documents with sensitive-looking fields.
Why it mattersThe database is readable without authentication — a direct breach of whatever private data it holds.
-
High
Elasticsearch/OpenSearch cluster allows anonymous index enumeration
An anonymous GET /_cat/indices succeeded — the cluster is unauthenticated, so all indices are world-accessible.
Why it mattersAn open cluster lets anyone enumerate indices and read (or delete) all documents — the classic mass-data-exposure class.
-
High
Elasticsearch index exposes sensitive data to anonymous queries
An anonymous _search of an index returned documents with sensitive-looking fields.
Why it mattersThe index is queryable without authentication — a direct breach of the private data it contains.
-
High
GraphQL backend exposes sensitive data to anonymous queries
An anonymous (or public-API-key) GraphQL query returned records containing sensitive-looking fields.
Why it mattersThe backend serves private data to unauthenticated callers — a direct data breach reachable straight from the client.
-
High
Anonymous read exposes sensitive data
An anonymous SELECT returned rows containing sensitive columns or sensitive values (PII, credentials, financial data).
Why it mattersAnyone can read private user data without authenticating — a direct data breach and a likely privacy/regulatory violation.
-
High
Anonymous writes accepted (RLS does not block unauthenticated writes)Off by default
An anonymous INSERT was accepted by the table's row-level-security policies.
Why it mattersAnyone on the internet can create or tamper with rows in this table — data integrity and, depending on the table, downstream trust are broken.
-
High
Firestore collection is world-readable (open security rules)
An anonymous read of a Firestore collection returned document data — the collection's `allow read` rule lets unauthenticated clients through.
Why it mattersAnyone can read the collection's documents (and, if writes are open, alter them) — a direct breach of the private data it holds.
-
High
Firebase Realtime Database is world-readable (open security rules)
An anonymous read of the Realtime Database root succeeded — the database's .read rule allows unauthenticated access.
Why it mattersAnyone can read (and, if .write is equally open, modify) the entire database — a full breach of all user data it stores.
-
High
Firebase Storage bucket lists objects to anonymous users (open security rules)
An anonymous list of the default Firebase Storage bucket returned object metadata — the Storage rules allow unauthenticated read/list.
Why it mattersAnyone can enumerate and download the bucket's files — a data breach if any object is private (uploads, documents, user media).
-
High
Cloud bucket is world-listable and holds private-looking files
An S3/GCS/Azure bucket allows anonymous listing, and the sampled object names match private-data patterns (backups, invoices, KYC, .env, …).
Why it mattersAnyone can enumerate and download the bucket's objects — a direct data breach of whatever private files it holds.
-
High
Supabase Storage bucket is world-listable and holds private-looking files
A Supabase Storage bucket returns objects to an anonymous list request, and the sampled names match private-data patterns.
Why it mattersA broken storage.objects RLS policy lets anyone enumerate and reach the bucket's private files — a data breach.
-
Medium
Likely unauthenticated access to sensitive data
An anonymous GET of an API route returned sensitive-looking (PII-shaped) fields — the endpoint appears to serve private data without authentication.
Why it mattersIf the endpoint is not meant to be public, anyone can read the sensitive data it returns — a broken-access-control breach. Labeled 'likely' because intent can be ambiguous.
-
Medium
Owner-less table readable across users (no per-user scoping — confirm intended)Deep scan
A table with no per-user ownership column returned a row readable by more than one user, so it has no per-user access scoping — and the rows carry sensitive data. Indistinguishable by structure alone from an intended public/shared table.
Why it mattersIf the table is meant to be per-user-private, any authenticated user can read others' sensitive rows — a horizontal data leak. If it is genuinely public/shared reference data this is expected. Held at medium pending confirmation because, without an owner column, a leak and a public table can't be told apart from the data.
-
Medium
Authenticated user can read another user's rows (no sensitive columns — confirm intended)Deep scan
A logged-in test user that owns no rows in a table could read another user's rows, but no sensitive columns were detected — possibly a public feed by design.
Why it mattersIf the table is meant to be per-user-private this is a horizontal leak; if it is a public feed it is expected. The absence of sensitive columns keeps this at medium pending confirmation.
-
Medium
Authenticated user can read other users' rows in a shared-looking table (confirm intended)Deep scan
A logged-in test user owns rows in a table AND can read rows owned by others — structurally identical to a legitimate shared/co-membership/public-profile table, so it cannot be confirmed a leak by data alone.
Why it mattersIf the table is genuinely shared (team roster, chat participants, public profiles) this is expected; if it is meant to be per-user-private it is a horizontal leak. Held at medium (the shared-table false-positive guard).
-
Medium
Authenticated user can write another user's row (writes not owner-scoped — confirm intended)Deep scanOff by default
A value-neutral update by a logged-in test user succeeded against another user's row — the write (UPDATE) policy is not scoped per owner.
Why it mattersIf the table is meant to be writable by non-owners (shared/collaborative/assignment) this is expected; otherwise an authenticated user can modify others' data — a horizontal-privilege-escalation write. Held at medium: the value-neutral test proves the policy is not owner-scoped, not an exploited takeover.
-
Medium
Anonymous writes accepted on an intake table (confirm intended)Off by default
An anonymous INSERT was accepted on a table that looks like an intake/submission form (contact, waitlist, feedback, signup).
Why it mattersPublic inserts may be by design here, but without validation and rate-limiting the table is open to spam, forged submissions, and storage abuse.
-
Medium
Cloud bucket allows anonymous listing (contents not obviously public)
An S3/GCS/Azure bucket allows anonymous listing; the objects are not recognizable public assets, so exposure is possible but unconfirmed.
Why it mattersAnonymous listing reveals every object name and lets anyone download them — a problem if any file is not meant to be public.
-
Medium
Supabase Storage bucket list is anonymously readable
An anonymous GET /storage/v1/bucket returns the project's bucket names — the storage bucket metadata is world-readable.
Why it mattersExposing the bucket inventory hands an attacker the exact names to target for object-listing and download attempts.
-
Medium
Supabase Storage bucket allows anonymous listing (contents not obviously public)
A Supabase Storage bucket is anonymously listable; the objects are not recognizable public assets, so exposure is possible but unconfirmed.
Why it mattersAnonymous listing exposes the object inventory and allows retrieval — a problem for any file not meant to be public.
-
Low
GraphQL introspection is enabled
The backend's GraphQL endpoint answers an introspection query, exposing the full schema (types, fields, operations).
Why it mattersIntrospection isn't a breach by itself, but it hands an attacker a complete map of your data model and mutations to target — a strong recon aid.
-
Info
BaaS collection is anonymously readable (no sensitive columns)
A PocketBase/Appwrite collection returned records to an anonymous request, but no sensitive field patterns were seen — likely public-by-design.
Why it mattersLow risk if the collection is meant to be public, but open anonymous reads are worth confirming as intentional.
-
Info
CouchDB database is anonymously readable (no sensitive columns)
An anonymous read of a CouchDB database returned documents, but no sensitive field patterns — likely public-by-design.
Why it mattersLow risk if the database is meant to be public, but anonymous read access is worth confirming as intended.
-
Info
Elasticsearch index is anonymously queryable (no sensitive fields)
An anonymous _search of an index returned documents, but no sensitive field patterns — likely a public search index.
Why it mattersLow risk if the index is a genuine public search corpus, but anonymous query access is worth confirming as intended.
-
Info
Table is anon-readable but holds no sensitive columns
An anonymous SELECT returned rows, but no sensitive column or value patterns were detected — likely intentionally public.
Why it mattersNot treated as a vulnerability. Recorded so the anon-readable surface is visible without crying wolf.
-
Info
Supabase RPC (stored-procedure) surface referenced by the app
The app's code calls Supabase RPC functions. A function defined SECURITY DEFINER runs with the definer's privileges and bypasses row-level security — an anon-callable one would be an RLS-bypass vector. This is presence-only: we detect the calls in the bundle but do NOT invoke the functions, so anon-callability and SECURITY DEFINER are unconfirmed.
Why it mattersAdvisory, not a confirmed vulnerability — it may be benign (the functions can be authenticated-only or SECURITY INVOKER). Surfaced so the RPC surface is auditable, because a SECURITY DEFINER function reachable by the anon role would silently bypass RLS.
-
Info
Cloud bucket allows anonymous listing (public assets)
An S3/GCS/Azure bucket allows anonymous listing and its objects look like public CDN assets (images, css, js).
Why it mattersLow risk if the bucket is genuinely a public asset store, but open listing still exposes the full inventory of files and their naming.
-
Info
Cloudflare R2 public bucket in use
A public r2.dev URL is referenced — an R2 bucket exposed through Cloudflare's public-by-design dev endpoint.
Why it mattersr2.dev serves objects publicly by design (no listing), so this is informational — the risk is only if private files were placed in a public R2 bucket.
-
Info
Supabase Storage bucket allows anonymous listing (public assets)
A Supabase Storage bucket is anonymously listable and its objects look like public assets.
Why it mattersLow risk if the bucket is a genuine public asset store, but open listing still exposes the full object inventory.
Secrets & credentials
43 checks-
High
Anthropic API key exposed
An Anthropic API key (sk-ant-…) was found in client-visible code.
Why it mattersThe key lets anyone bill Claude API usage to your account and read/abuse your Anthropic access — direct financial exposure.
-
High
AWS access key + secret pair exposed
An AWS access key id (AKIA…/ASIA…) was found alongside its 40-character secret access key in client-visible code — a complete, immediately-usable credential.
Why it mattersAnyone who reads it can authenticate to your AWS account with whatever IAM permissions the key holds — commonly read/write to S3, databases, compute, and more. This is a live, ready-to-use credential, not just an identifier.
-
High
Azure Storage account key exposed
An Azure Storage AccountKey= shared key was found in client-visible code.
Why it mattersThe shared key grants full control of the storage account — read, write, and delete on every blob, file, queue, and table it holds.
-
High
Database connection string with embedded credentials exposed
A database URL containing an inline user:password (Postgres/MySQL/MongoDB/Redis/AMQP) was found in client-visible code.
Why it mattersThe credentials grant direct database access — an attacker can connect and read, alter, or destroy your data, bypassing the application entirely.
-
High
DigitalOcean token exposed
A DigitalOcean personal access token (dop_v1_/doo_v1_/dor_v1_) was found in client-visible code.
Why it mattersThe token grants API control of your DigitalOcean account — create/destroy droplets, databases, and DNS, and read account data.
-
High
Docker Hub access token exposed
A Docker Hub access token (dckr_pat_…) was found in client-visible code.
Why it mattersThe token lets an attacker push malicious images to your Docker Hub repositories — a supply-chain compromise of anyone pulling them.
-
High
Doppler service token exposed
A Doppler token (dp.pt.… / dp.st.… …) was found in client-visible code.
Why it mattersDoppler holds your secrets — a leaked service token can read the secret values for a config/project, exposing every credential it manages.
-
High
Secret exposed in client code (high-entropy value on a secret-named variable)
A high-entropy value assigned to a secret-named variable (e.g. SESSION_SECRET, JWT_SIGNING_KEY, api_secret, db_password, client_secret) was found in client-visible code — a credential regardless of provider prefix.
Why it mattersThe value is almost certainly a live secret — a session/JWT signing key, API secret, database password, or client secret. Anyone who reads it can forge sessions or tokens, call privileged APIs, or access the backing service directly.
-
High
GitHub fine-grained PAT exposed
A GitHub fine-grained personal access token (github_pat_…) was found in client-visible code.
Why it mattersThe token grants its configured repo/org permissions — potentially read/write to code and settings, enabling source theft or a malicious commit.
-
High
GitHub token exposed
A GitHub token (ghp_/gho_/ghu_/ghs_/ghr_) was found in client-visible code.
Why it mattersDepending on scope, the token grants read/write access to your repositories, Actions, and org resources — source-code theft or a supply-chain push.
-
High
GitLab personal access token exposed
A GitLab personal access token (glpat-…) was found in client-visible code.
Why it mattersThe token grants its scoped access to your GitLab projects and API — potentially source-code and CI/CD control.
-
High
Google OAuth client secret exposed
A Google OAuth client secret (GOCSPX-…) was found in client-visible code.
Why it mattersThe client secret lets an attacker impersonate your OAuth application, forge token exchanges, and abuse your Google API quota and consent screen.
-
High
Groq API key exposed
A Groq API key (gsk_…) was found in client-visible code.
Why it mattersThe key grants API access to your Groq account — others can run inference against your account and quota, at your cost.
-
High
Hugging Face access token exposed
A Hugging Face access token (hf_…) was found in client-visible code.
Why it mattersThe token grants API access to your Hugging Face account — private models/datasets and, if write-scoped, the ability to alter them.
-
High
Linear API key exposed
A Linear API key (lin_api_…) was found in client-visible code.
Why it mattersThe key grants API access to your Linear workspace — reading and modifying issues, projects, and team data.
-
High
Mailchimp API key exposed
A Mailchimp API key (<hex>-usN, corroborated by a nearby 'mailchimp' token) was found in client-visible code.
Why it mattersThe key grants API access to your Mailchimp account — audience/subscriber data (PII) and the ability to send campaigns as you.
-
High
Mapbox secret token exposed
A Mapbox secret token (sk.…) was found in client-visible code.
Why it mattersUnlike a public pk. token, a Mapbox secret token can manage your account and tokens — abuse of your account and billing.
-
High
Netlify personal access token exposed
A Netlify personal access token (nfp_…) was found in client-visible code.
Why it mattersThe token grants API control of your Netlify account — deploy or delete sites, read build environment variables (which often hold other secrets), and change DNS.
-
High
New Relic API key exposed
A New Relic API key (NRAK-…) was found in client-visible code.
Why it mattersThe key grants API access to your New Relic account — reading telemetry and managing configuration, depending on type.
-
High
OpenAI API key exposed
An OpenAI API key (sk-…, incl. sk-proj-/sk-svcacct-) was found in client-visible code.
Why it mattersThe key lets anyone bill OpenAI usage to your account and abuse your access — direct financial exposure and quota theft.
-
High
Perplexity API key exposed
A Perplexity API key (pplx-…) was found in client-visible code.
Why it mattersThe key grants API access to your Perplexity account — others can run queries against your account and quota, at your cost.
-
High
PlanetScale database token exposed
A PlanetScale password or service token (pscale_pw_… / pscale_tkn_…) was found in client-visible code.
Why it mattersThe token grants direct database access — reading and writing your production data. Treat it as a full database credential.
-
High
Private key exposed (PEM key block)
A PEM-encoded private key block (RSA/EC/DSA/OpenSSH/encrypted PKCS#8/PGP) was found in client-visible code.
Why it mattersA leaked private key lets an attacker impersonate your server/service, decrypt intercepted traffic, or sign malicious artifacts as you.
-
High
PyPI upload token exposed
A PyPI upload token (pypi-AgEIcHlwaS…) was found in client-visible code.
Why it mattersThe token lets an attacker publish malicious releases of your Python packages — a supply-chain compromise of downstream installers.
-
High
SendGrid API key exposed
A SendGrid API key (SG.…) was found in client-visible code.
Why it mattersThe key lets an attacker send email as your domain (phishing/spam from your reputation) and read your email activity.
-
High
Shopify access token exposed
A Shopify access token (shpat_/shpca_/shppa_/shpss_) was found in client-visible code.
Why it mattersThe token grants API access to the connected Shopify store — orders, customer PII, and store configuration, depending on scope.
-
High
Slack token exposed
A Slack token (xoxb-/xoxp-/xoxa-/xoxr-/xoxs-/xoxe-/xapp-) was found in client-visible code.
Why it mattersThe token grants API access to your Slack workspace — reading messages/files and posting as the app or user, depending on scope.
-
High
Square access token exposed
A Square access token (sq0atp-/sq0csp-) was found in client-visible code.
Why it mattersThe token grants API access to your Square account — payments, orders, and customer data, depending on scope.
-
High
Stripe live secret key exposed
A Stripe sk_live_ secret key was found in client-visible code.
Why it mattersThe live secret key can move real money — create charges and refunds, read customer/payment data, and manage your account via the API.
-
High
Supabase secret key exposed (sb_secret_)
A Supabase sb_secret_ secret key was found in client-visible code.
Why it mattersThis is a privileged server key that bypasses Row-Level Security — it grants full read/write access to your database.
-
High
Supabase service_role key exposed
A Supabase service_role JWT was found in client-visible code — this key bypasses Row-Level Security.
Why it mattersAnyone who reads it gets full, RLS-bypassing read/write access to every table in your database — total data compromise.
-
Medium
AWS access key id exposed
An AWS access key id (AKIA…/ASIA…) was found in client-visible code, with no secret access key alongside it.
Why it mattersPaired with its secret, an AWS key grants whatever IAM permissions it holds — often broad access to storage, compute, and data. The key id alone confirms an AWS credential is in play; find and rotate the pair.
-
Medium
Figma personal access token exposed
A Figma personal access token (figd_…) was found in client-visible code.
Why it mattersThe token grants API access to your Figma files and projects — reading (and depending on scope, modifying) design content.
-
Medium
Mailgun API key exposed
A Mailgun API key (key-…, corroborated by a nearby 'mailgun' token) was found in client-visible code.
Why it mattersThe key lets an attacker send email through your Mailgun account — phishing/spam that spends your reputation and quota.
-
Medium
npm token exposed
An npm access token (npm_…) was found in client-visible code.
Why it mattersA publish-scoped npm token lets an attacker push malicious versions of your packages — a supply-chain compromise of everyone who installs them.
-
Medium
Postman API key exposed
A Postman API key (PMAK-…) was found in client-visible code.
Why it mattersThe key grants API access to your Postman account — reading and modifying collections, environments (which often store secrets), and workspaces.
-
Medium
Slack incoming webhook URL exposed
A Slack incoming-webhook URL (hooks.slack.com/services/…) was found in client-visible code.
Why it mattersThe URL lets anyone post arbitrary messages into the connected Slack channel — spam or convincing internal phishing.
-
Medium
Stripe restricted key exposed
A Stripe rk_live_ restricted key was found in client-visible code.
Why it mattersA restricted key is scoped, but still grants whatever permissions it was created with against live data — a real, if bounded, exposure.
-
Medium
Stripe test secret key exposed
A Stripe sk_test_ test-mode secret key was found in client-visible code.
Why it mattersNo real money moves in test mode, but the key exposes test data and API access and signals that secret keys are being shipped to the client — the live key may be next.
-
Medium
Stripe webhook signing secret exposed
A Stripe whsec_ webhook signing secret was found in client-visible code.
Why it mattersThe signing secret lets an attacker forge webhook events your backend will accept as genuine — e.g. faking a successful payment.
-
Medium
Telegram bot token exposed
A Telegram bot token (<id>:AA…) was found in client-visible code.
Why it mattersThe token grants full control of your Telegram bot — reading its messages and sending as it to every chat it's in.
-
Medium
Twilio API key exposed
A Twilio API key (SK…, corroborated by a nearby 'twilio' token) was found in client-visible code.
Why it mattersThe key lets an attacker send SMS/voice and read messaging logs on your Twilio account — toll fraud and data exposure.
-
Info
Google/Firebase API key found
A Google/Firebase browser API key (AIza…) was found in client-visible code. These are usually public by design and meant to be referrer/app-restricted.
Why it mattersNot a leak on its own — Google web/Firebase API keys are designed to be public. The risk is only if the key is UNrestricted, letting others spend against your Google Cloud quota or reach unintended APIs.
Exposed files & disclosure
34 checks-
High
Spring Boot actuator /env exposes configuration
The Spring Boot actuator /env endpoint is public and dumps the app's property sources.
Why it mattersThe /env dump exposes environment variables, configuration, and often credentials — a direct information-disclosure and pivot vector.
-
High
Spring Boot actuator heap dump downloadable
The Spring Boot actuator /heapdump endpoint is public, serving a full JVM heap dump.
Why it mattersA heap dump contains in-memory secrets, session tokens, and live request/response data — a severe disclosure that often yields credentials.
-
High
AWS credentials file publicly served
An ~/.aws/credentials INI file exposing aws_access_key_id / aws_secret_access_key is downloadable.
Why it mattersThe keys grant whatever IAM permissions the profile holds — often broad access to storage, compute, and data across your AWS account.
-
High
Backup archive publicly served
A ZIP archive (backup.zip / www.zip / public_html.zip) — confirmed by its archive magic bytes — is downloadable.
Why it mattersA public backup archive typically contains the full site source, config, and often a database dump — a comprehensive breach in one file.
-
High
Plaintext credentials file publicly served
A plaintext credentials file (~/.netrc or ~/.pgpass) is downloadable and returns real credential lines, not HTML.
Why it mattersThese files hold plaintext logins — FTP/HTTP credentials (.netrc) or database host:port:db:user:password (.pgpass) — that an attacker can use directly.
-
High
Docker registry credentials publicly served
A Docker CLI config (~/.docker/config.json) with an `auths` block is served publicly.
Why it mattersThe `auths` block holds base64-encoded registry username:password pairs — an attacker can pull (and often push) your private container images.
-
High
Environment file (.env) publicly served
A .env-style environment file (any variant — .env, .env.production, .env.bak, …) is downloadable and returns real KEY=value lines, not an HTML page.
Why it mattersEnvironment files typically hold the app's most privileged secrets — database URLs, API keys, signing secrets — so this is often a direct path to full compromise. Any keys inside are reported separately.
-
High
Kubernetes kubeconfig publicly served
A kubeconfig (~/.kube/config) with cluster credentials is served publicly.
Why it mattersA kubeconfig grants API access to the cluster — client certificates/keys or a bearer token that an attacker can use to read secrets, deploy workloads, or take over the cluster.
-
High
Private key file publicly served
A PEM private key (e.g. .ssh/id_rsa, id_rsa) is downloadable.
Why it mattersA leaked private key lets an attacker authenticate as the server/user, decrypt intercepted traffic, or sign artifacts as you.
-
High
Rails database.yml with credentials publicly served
A Rails config/database.yml (or /database.yml) is served publicly and contains a literal database password.
Why it mattersThe file exposes the database adapter, host, and a plaintext password — direct database access, bypassing the application.
-
High
Cloud service-account key file publicly served
A GCP/Firebase service-account or OAuth credential file (serviceAccount.json, firebase-adminsdk.json, credentials.json) with a private_key is downloadable.
Why it mattersA service-account key grants programmatic access to the whole cloud project and — for Firebase admin — bypasses all Security Rules. This is a full-project compromise.
-
High
Deploy (SFTP) credentials publicly served
A VS Code SFTP deploy config (.vscode/sftp.json) exposing a host plus a password or private-key path is downloadable.
Why it mattersThe file gives an attacker the deploy server's address and login material — enough to connect and modify the live site.
-
High
SQL database dump publicly served
A SQL dump (backup.sql / dump.sql / database.sql) with CREATE TABLE / INSERT statements is downloadable.
Why it mattersA public database dump is a full data breach — all rows, including user PII and any credentials stored in the database, can be downloaded.
-
High
Terraform state publicly served
A Terraform state file (terraform.tfstate) is downloadable.
Why it mattersTerraform state routinely stores provider credentials and resource secrets in plaintext — a direct route to your cloud infrastructure.
-
High
WordPress config backup leaks DB credentials
A wp-config.php backup (wp-config.php.bak/~/.save/.old) is served as raw source, exposing DB_PASSWORD and auth salts.
Why it mattersThe backup reveals database credentials and WordPress secret keys — enough to access the database directly and forge authentication.
-
Medium
Spring Boot actuator endpoints exposed
The Spring Boot actuator index is public, listing management endpoints (env, beans, mappings, …).
Why it mattersThe endpoint list reveals internal application detail and points an attacker at higher-value actuator endpoints to probe next.
-
Medium
docker-compose file publicly served
A docker-compose.yml/.yaml is served publicly, exposing service environment variables and topology.
Why it mattersCompose files leak inline environment variables (often secrets), image names, and service wiring an attacker can use to map and target your stack.
-
Medium
.NET appsettings.json with secrets exposed
A .NET appsettings.json carrying ConnectionStrings or other secrets is served publicly.
Why it mattersConnection strings and secrets in appsettings hand an attacker direct database/service credentials.
-
Medium
Git repository metadata exposed (.git)
Git internals (.git/config, .git/HEAD, or .git/logs/HEAD) are served publicly.
Why it mattersAn exposed .git directory is often fully downloadable, letting an attacker reconstruct your complete source code, commit history, author details, and any secrets ever committed.
-
Medium
Laravel log file publicly served
The Laravel application log (storage/logs/laravel.log) is served publicly.
Why it mattersApplication logs leak stack traces, file paths, query fragments, and occasionally secrets — useful reconnaissance for an attacker.
-
Medium
.npmrc auth token publicly served
An .npmrc (or similar registry config) containing a _authToken / _auth / _password is downloadable.
Why it mattersA registry auth token can let an attacker read private packages and, if publish-scoped, push malicious versions — a supply-chain risk.
-
Medium
phpinfo() output publicly served
A phpinfo() page is publicly reachable (e.g. /phpinfo.php).
Why it mattersphpinfo() discloses the PHP version, loaded modules, full configuration, absolute filesystem paths, and server environment variables — the latter can include database URLs and API keys — giving an attacker a detailed map for a targeted attack.
-
Medium
Config file with sensitive keys exposed
A JSON config file (e.g. config.json) served publicly contains sensitive-looking keys (api_key, secret, password, token).
Why it mattersA config file with credential-shaped fields exposes secrets or internal wiring an attacker can use directly or to pivot. Any recognizable keys are reported separately.
-
Medium
Apache server-status publicly served
The Apache mod_status page (/server-status) is publicly reachable.
Why it mattersserver-status streams live request URLs, client IPs, virtual-host names, and server internals — an attacker can monitor real traffic and enumerate endpoints and users.
-
Medium
WordPress debug.log publicly served
The WordPress /wp-content/debug.log is served publicly, exposing PHP errors and stack traces.
Why it mattersDebug logs leak file paths, plugin internals, SQL errors, and sometimes secrets — reconnaissance that guides deeper attacks.
-
Low
.DS_Store index exposed
A macOS .DS_Store file is served publicly; it discloses the names of other files in the directory.
Why it mattersLow on its own, but it reveals hidden/adjacent file and directory names that guide an attacker toward more sensitive targets.
-
Low
WordPress usernames enumerable via REST API
The WordPress /wp-json/wp/v2/users endpoint returns the site's usernames.
Why it mattersEnumerable usernames remove a factor from credential attacks — an attacker now only needs passwords, and can target specific accounts.
-
Low
WordPress XML-RPC enabled
The WordPress /xmlrpc.php endpoint is enabled and responding.
Why it mattersXML-RPC enables brute-force amplification (system.multicall bundles many password guesses per request) and can be abused as a pingback DDoS relay.
-
Low
GraphQL introspection is enabled
The API's GraphQL endpoint answers an introspection query, exposing the full schema (queries, mutations, types).
Why it mattersIntrospection isn't a breach by itself, but it hands an attacker a complete map of the API's operations and data model to target.
-
Low
API specification is publicly exposed
An OpenAPI/Swagger specification is served publicly, documenting every route and parameter of the API.
Why it mattersOften intentional, but a public spec hands an attacker the full API map — routes, parameters, and auth requirements — to probe.
-
Low
Source map exposes original application source
A JavaScript bundle references a publicly-served .map file whose sourcesContent reconstructs the original, un-minified source (comments, internal logic, endpoints).
Why it mattersThe recovered source hands an attacker your client-side logic, internal API endpoints, and any secrets or comments the minifier had obscured — a strong reconnaissance boost, and occasionally a direct secret leak.
-
Info
Server banner discloses version
The Server response header includes a version number.
Why it mattersVersion disclosure narrows an attacker's search to CVEs affecting that exact release.
-
Info
Framework disclosed via X-Powered-By
The X-Powered-By response header advertises the server framework (and sometimes its version).
Why it mattersNot exploitable on its own, but it hands an attacker precise version/framework intel for targeting known CVEs.
-
Medium
Server error / debug page exposed
The site served a framework debug or stack-trace page instead of a generic error — leaking its framework and version, server file paths, and often source snippets, SQL, or configuration.
Why it mattersA stack trace / debug page hands an attacker a map of your stack: framework and version, absolute server paths, source snippets, query fragments, and sometimes credentials or environment values — a strong foothold for a targeted attack. It usually means production is running with debug mode on.
Transport & TLS
13 checks-
High
TLS certificate has expired
The certificate the site serves for HTTPS is past its expiry date.
Why it mattersEvery browser shows a full-page security warning and blocks the site — visitors cannot reach it, and the padlock/trust signal is gone.
-
High
TLS certificate is not yet valid
The served certificate's start (not-before) date is in the future, so it isn't valid yet.
Why it mattersClients reject the certificate and show a security warning until its start date — often a sign of a misconfigured deploy or a wrong server clock.
-
Medium
TLS certificate is expiring soon
The served certificate is valid now but expires within the next 30 days.
Why it mattersIf renewal is missed the certificate will lapse and browsers will block the site — a self-inflicted outage.
-
Medium
TLS certificate does not match the hostname
The served certificate's subject/SAN names do not cover the hostname being visited.
Why it mattersBrowsers show a name-mismatch warning and block the site. (If the host is fronted by a CDN/proxy that terminates TLS elsewhere this can be benign — confirm which edge serves the name.)
-
Medium
TLS certificate is self-signed / not from a trusted CA
The certificate is self-issued (issuer equals subject), so it does not chain to a publicly trusted certificate authority.
Why it mattersPublic clients do not trust it and show a security warning, and users are trained to click through warnings — which also masks real man-in-the-middle attacks.
-
Medium
TLS certificate uses a weak (short) RSA key
The served certificate's RSA public key is smaller than the 2048-bit minimum.
Why it mattersSub-2048-bit RSA keys are considered factorable at scale and fail NIST and CA/Browser Forum baselines; a served short key usually means an internal or long-outdated certificate.
-
Medium
TLS certificate uses a weak signature algorithm
The served leaf certificate is signed with a collision-broken hash (SHA-1, MD5, or MD2).
Why it mattersCollision attacks against SHA-1/MD5 make it feasible to forge a certificate a client would accept; modern browsers already reject SHA-1-signed leaf certificates, so this also breaks compatibility. A served weak-signed leaf usually means an internal or long-outdated certificate authority.
-
Low
Deprecated TLS 1.0 / 1.1 still accepted
The server still completes handshakes over TLS 1.0 and/or 1.1, which are formally deprecated.
Why it mattersDeprecated protocols carry known weaknesses and fail PCI-DSS and modern browser baselines; on their own they are a hygiene/compliance issue rather than a live exploit (many CDN edges still allow them by default).
-
Medium
Broken cipher suites accepted
The server negotiated a genuinely broken cipher (RC4, EXPORT, or NULL) from a weak-only ClientHello.
Why it mattersThese ciphers are cryptographically broken — traffic protected by them can be decrypted or was never encrypted at all (NULL), undermining confidentiality.
-
Medium
Weak cipher negotiated when strong suites were offered
Even when offered strong suites, the server chose a weak (non-AEAD) cipher.
Why it mattersThe server's cipher preference favours a weaker algorithm, so ordinary clients get weaker-than-necessary encryption for their traffic.
-
Low
Legacy 3DES cipher accepted
The server accepts the legacy 3DES (Triple-DES) cipher suite.
Why it matters3DES is deprecated (Sweet32 birthday attack against 64-bit block ciphers) though not outright broken; it is common on default edges, so this is a hardening/compliance item.
-
Low
No forward secrecy (static-RSA key exchange)
The server negotiated a static-RSA key-exchange cipher even though modern ECDHE suites were offered, so sessions have no forward secrecy.
Why it mattersWithout forward secrecy, a single future compromise of the server's private key lets an attacker who recorded past traffic decrypt all of it retroactively. ECDHE/DHE and TLS 1.3 avoid this by using ephemeral keys.
-
Low
HSTS max-age is very short or zero
Strict-Transport-Security is set but with a max-age under a day (or 0).
Why it mattersA short window leaves users exposed to SSL-stripping downgrade attacks outside it; max-age=0 actively clears any prior HSTS pin.
Browser & web hardening
11 checks-
Low
Content-Security-Policy present but weak
A CSP exists but its script policy allows unsafe-inline, unsafe-eval, or a wildcard source.
Why it mattersThese directives largely defeat CSP's core purpose — blocking injected script — so an XSS flaw executes despite the policy.
-
Info
Standard hardening headers absent
One or more defense-in-depth response headers (HSTS, CSP, X-Content-Type-Options, frame protection, Referrer-Policy) are missing.
Why it mattersAbsence is not directly exploitable, but each missing header removes a layer that would blunt XSS, clickjacking, MIME-sniffing, or referrer leakage.
-
Medium
Session cookie missing HttpOnly
A session-looking cookie is readable by JavaScript because it lacks the HttpOnly attribute.
Why it mattersAny cross-site-scripting flaw can read the session cookie and exfiltrate it, escalating XSS to full account takeover.
-
Medium
Session cookie missing Secure
A session-looking cookie is set without the Secure attribute on an HTTPS site.
Why it mattersThe cookie can be transmitted over plain HTTP and intercepted by an on-path attacker, hijacking the session.
-
Low
Session cookie missing SameSite
A session-looking cookie has no SameSite attribute.
Why it mattersIncreases cross-site-request-forgery exposure: the cookie is sent on cross-site requests unless another CSRF defense is present.
-
Medium
CORS allows the `null` origin with credentials
The server returns Access-Control-Allow-Origin: null together with Access-Control-Allow-Credentials: true.
Why it mattersThe null origin is attacker-reachable — a sandboxed iframe, a data:/file: document, or certain redirects all send Origin: null — so any of those contexts can make credentialed cross-origin requests and read the victim's authenticated responses.
-
Medium
CORS reflects arbitrary origins with credentials
The server echoes any request Origin back in Access-Control-Allow-Origin together with Access-Control-Allow-Credentials: true.
Why it mattersAny website a victim visits can make credentialed cross-origin requests and read the responses — effectively reading the victim's authenticated data.
-
Medium
CORS allows any origin with credentials
Access-Control-Allow-Origin: * is sent together with Access-Control-Allow-Credentials: true.
Why it mattersBrowsers reject this combination, but its presence signals a misconfigured CORS layer; a fix that swaps `*` for origin-reflection would become directly exploitable.
-
Info
CORS allows the `null` origin (no credentials)
The server returns Access-Control-Allow-Origin: null, but without credentials.
Why it mattersLow-risk without credentials, but the null origin is attacker-reachable (sandboxed iframe / data: document), so any endpoint that starts trusting Origin would be exposed.
-
Info
CORS reflects arbitrary origins (no credentials)
The server echoes any request Origin back in Access-Control-Allow-Origin, but without credentials.
Why it mattersLow-risk on its own (equivalent to `*`), but any endpoint that later starts relying on Origin for trust would be exposed.
-
Info
CORS allows any origin (no credentials)
Access-Control-Allow-Origin: * without credentials — common and low-risk for public data.
Why it mattersFine for genuinely public resources; a concern only if a private endpoint sits behind the same wildcard policy.
Identity & email
11 checks-
Medium
Cognito identity pool grants AWS credentials to anonymous clients
An AWS Cognito identity pool allows unauthenticated access, so an anonymous request obtains temporary AWS credentials with no sign-in.
Why it mattersThe blast radius equals the unauthenticated IAM role's permissions. If that guest role can read/write S3, DynamoDB, or invoke other AWS APIs, anyone on the internet inherits that access. Even a tightly-scoped role is worth confirming, since the pool id is public in the app.
-
Low
Firebase authorized domains include a wildcard
The Firebase project's authorizedDomains list contains a wildcard entry, widening the OAuth redirect surface.
Why it mattersAn over-broad authorized-domain allow-list increases the chance an OAuth redirect/callback can be pointed at an attacker-controlled host, aiding token/credential theft.
-
Info
Clerk open registration is enabled
The Clerk environment config (readable from the public Frontend API with the publishable key) shows sign-up mode is "public" — anyone can self-register.
Why it mattersOpen registration is often intentional, but where authorization checks only 'is the request signed in' (not per-user ownership), self-signup turns 'authenticated' into 'anyone' — a fresh account reaches data meant for real users.
-
Info
Firebase open registration is enabled
The Firebase project config (readable with the public web API key) shows email/password sign-up is open to anyone.
Why it mattersOpen registration is often intentional, but combined with weak Firestore/RTDB rules it lets an attacker create an account and reach any data that is protected only by `request.auth != null` — turning 'authenticated' into 'anyone'.
-
Info
No DMARC record — spoofed mail is not rejected
The domain publishes no DMARC (_dmarc, v=DMARC1) policy, so mailbox providers have no instruction to quarantine or reject failing mail.
Why it mattersEven with SPF/DKIM configured, without DMARC there is no enforcement policy — spoofed mail that fails those checks can still be delivered.
-
Info
DMARC does not protect this subdomain
This subdomain has no DMARC record of its own, and the organizational domain's policy does not enforce on subdomains (sp=none, or no sp= tag with p=none) — so mail spoofing this subdomain is not rejected.
Why it mattersAttackers can spoof mail from this subdomain even though the apex may look protected — subdomains are a common phishing vector precisely because their DMARC coverage is overlooked.
-
Info
DMARC policy not enforced (p=none)
The DMARC record uses p=none (monitor-only) or omits the required p= tag, so failing mail is still delivered.
Why it mattersp=none reports abuse but does not stop it — mail failing SPF/DKIM is still delivered, so spoofing of your domain is not actually prevented.
-
Info
No SPF record — sender spoofing is unrestricted
The domain publishes no SPF (v=spf1) TXT record, so receivers have no authorized-sender policy to check.
Why it mattersAnyone can send mail with a forged From: address at this domain and it will not fail SPF — enabling phishing and business-email-compromise that appears to come from you.
-
Info
Multiple SPF records — policy is undefined
The domain publishes more than one v=spf1 record; per RFC 7208 this is a permerror and SPF may be ignored entirely.
Why it mattersWith SPF evaluation undefined, receivers may skip the check — leaving spoofed mail unfiltered as if no policy existed.
-
Info
SPF is neutral (?all) — no enforcement
The SPF record ends in "?all" (neutral): it expresses no pass/fail policy.
Why it mattersSpoofed mail is neither authorized nor rejected, so SPF provides no protection against forgery of your domain.
-
Info
SPF authorizes any sender (+all)
The SPF record ends in "+all", which explicitly authorizes every host on the internet to send as this domain.
Why it matters"+all" is equivalent to publishing no policy — any server can send mail that passes SPF for your domain.
Supply chain, DNS & AI surface
9 checks-
Medium
WordPress core is significantly outdated
The detected WordPress core version is on a branch several releases behind the current line, so it is missing the accumulated security fixes WordPress backports to maintained branches.
Why it mattersAn outdated core accumulates publicly-known, mass-exploited vulnerabilities (SQL injection, privilege escalation, RCE across releases). Labeled 'likely' because the version is inferred from the page — but a core this far behind is a high-value target for automated attacks.
-
Medium
WordPress plugin with a known vulnerability
A WordPress plugin was detected at a version below the patch for a known CVE (the version is inferred from the plugin's asset URL).
Why it mattersKnown plugin CVEs are widely exploited on WordPress sites — depending on the flaw this can mean stored XSS, SQL injection, auth bypass, or remote code execution. Labeled 'likely' because the version is inferred, not confirmed.
-
Medium
Outdated JavaScript library with known vulnerabilities
A client-side JavaScript library is loaded at a version below the fix for one or more known CVEs (the version is observed in a script URL or the library's own version banner).
Why it mattersKnown library CVEs (typically DOM XSS, prototype pollution, or ReDoS) can be exploitable if the affected feature is reachable with untrusted input. Kept at medium on a passive signal — presence is certain, but reachability of the vulnerable code path is not.
-
Low
WordPress plugin present — version could not be confirmed
A WordPress plugin with a known CVE history was detected, but its version could not be read from the page assets — so vulnerability can't be confirmed or ruled out.
Why it mattersOnly a pointer, not a confirmed finding: if the installed version is below the patch it is exploitable; if it's current it's fine. Worth confirming because this plugin has a known vulnerable range.
-
Low
Third-party subresource loaded without Subresource Integrity
A cross-origin (third-party) subresource — a <script>, stylesheet, or module/preload — is loaded without a Subresource Integrity (SRI) hash, so the browser can't verify the file wasn't tampered with before running or applying it.
Why it mattersIf the third-party host or its CDN is compromised — or the response is altered in transit — attacker-controlled code (or CSS that can exfiltrate/deface) runs in your site's origin with access to the DOM, cookies, and any in-page secrets. An SRI hash pins the exact file the browser will accept and rejects anything else. Kept at low: it's a defense-in-depth gap, not an active vulnerability on its own.
-
Low
Subresource Integrity present but not enforced (missing crossorigin)
A cross-origin subresource carries an `integrity` hash but no `crossorigin` attribute. On a cross-origin resource the browser fetches in no-cors mode and gets an opaque response it cannot read, so the SRI hash is silently NOT enforced — the pin does not take effect.
Why it mattersThe developer intended to pin the file, but the check does nothing: the resource is typically blocked outright (a broken page), or in some paths loads unverified — either way the integrity guarantee they think they have is absent. A one-attribute misconfiguration that defeats the protection it looks like it provides.
-
High
Possible subdomain takeover (dangling DNS record)
A DNS record (via CNAME) points at a hosting service resource (S3 bucket, GitHub Pages site, Heroku app, …) that is unclaimed — the service returned its distinctive 'unregistered' response.
Why it mattersAn attacker who registers that unclaimed name on the service can serve arbitrary content on your subdomain — enabling convincing phishing, cookie/session theft (same registrable domain), and content spoofing under your brand.
-
Medium
Client-visible MCP / AI-agent configuration
AI-agent / Model Context Protocol wiring is reachable from the client (an mcpServers block, MCP SDK, or an MCP server reference).
Why it mattersIf an agent with tool access reads user-controlled data (rows, documents, messages), malicious stored values can steer it into unintended actions — data-plane (indirect) prompt injection. This is presence-only detection, not a confirmed exploit.
-
Info
AI / LLM surface present
A client-visible AI/LLM integration was detected — an LLM provider host called from the browser and/or an agent framework in the bundle.
Why it mattersInformational: a browser-side LLM call risks exposing the provider API key and turns model output into an untrusted-input (output-handling / XSS) surface. Presence only.
Injection
1 checks-
High
Reflected cross-site scripting (XSS) — injected script executed in the browserDeep scan
A value taken from the URL was reflected into the page and ran as JavaScript in the visitor's browser — proven by executing a benign marker payload, not merely by reflecting it.
Why it mattersAn attacker who gets a victim to open a crafted link can run arbitrary JavaScript in your site's origin as that visitor: read or steal session tokens and cookies, act as the user, alter anything the page can, and phish convincingly from your own domain. Because execution was proven (not just reflection), this is directly exploitable.
This list is generated from the same catalog that powers every report, so it always reflects what the scanner actually checks — the machine-readable version is at /coverage.json. New detections are added over time. How scanning works · Ask about a specific check.
Vulnerability data sources
The version-based checks above match against public vulnerability feeds, which we mirror on a schedule rather than query live.
- WordPress plugin and theme vulnerability data from Wordfence Intelligence. www.wordfence.com
- JavaScript package vulnerability data from OSV.dev, which aggregates the GitHub Advisory Database and the OSV malicious-packages database. osv.dev
- Known-exploited-vulnerability flags from the CISA Known Exploited Vulnerabilities catalog (US government, public domain). www.cisa.gov
- CVE identifiers and records are © the MITRE Corporation. www.cve.org