hasura-security
v0.1.0
Published
Audit any self-hosted Hasura GraphQL endpoint for the misconfigs that actually leak data — open introspection without the admin secret, the anonymous 'public' unauthorized role exposing tables/columns/rows, and an unauthenticated console — and PROVE each
Downloads
127
Maintainers
Readme
hasura-security
Audit any self-hosted Hasura GraphQL endpoint for the misconfigurations that actually leak data — GraphQL introspection answered without the admin secret, the anonymous
publicunauthorized role exposing tables and columns, queryable rows leaking with no auth header, and an unauthenticated console — and prove each one live with an anonymous probe. Other checklists tell you what might be wrong; this fetches the bytes and shows you what is.
⚡ Run it in one line, no admin secret, no install:
npx hasura-security --url https://your-hasura.example.com
🤝 Want it done for you? Fixed-scope audit — $99 / 24h: I verify each finding live and send a written report with the exact config fixes.
$ npx hasura-security --url https://hasura.example.com
2 critical, 2 high, 0 medium — 4 CONFIRMED via anonymous probe
CRITICAL /v1/graphql anonymous 'public' role answers queries — no auth header
CRITICAL /v1/graphql { users } public role leaks rows — 1 reachable with no secret
HIGH /v1/graphql introspection answered without the admin secret
HIGH /console admin console reachable unauthenticatedWhy this exists
Hasura is one of the most deployed instant-GraphQL backends, and it ships with
one famous footgun: HASURA_GRAPHQL_UNAUTHORIZED_ROLE. Set it to public
(a hugely common tutorial copy-paste) and grant that role any SELECT, and a
request with no admin secret and no Authorization header can query your
data — Hasura itself documents this, and it's the heart of
hasura/graphql-engine#5501
("unrestricted access using HASURA_GRAPHQL_UNAUTHORIZED_ROLE=public downloads
the whole schema with no auth header").
On top of that, GraphQL introspection left on in production is a top recurring finding across HackerOne reports, the PortSwigger Web Security Academy, and OWASP: it hands an attacker your entire data model.
hasura-security checks for these and confirms the real ones by issuing the
exact anonymous request an attacker would — so you triage facts, not maybes.
What it checks
| Check | Severity | How it's confirmed |
|---|---|---|
| No admin secret set at all | critical | anonymous run_sql / export_metadata on /v2/query succeeds |
| Anonymous public unauthorized role | critical | a bare GraphQL query is answered with no admin secret / Authorization header |
| Queryable rows leaking via the public role | critical | anonymous { table(limit:1) } returns rows |
| Introspection answered without the secret | high | __schema query answered anonymously on /v1/graphql |
| Console reachable unauthenticated | high | GET /console serves the admin UI with no secret prompt |
Usage
# Probe a live instance (auto-discovers table fields from anonymous introspection)
npx hasura-security --url https://hasura.example.com
# Probe specific query-root fields (tables) for row leakage
npx hasura-security --url https://hasura.example.com --tables users,orders
# Write a shareable HTML report
npx hasura-security --url https://hasura.example.com --html report.html
# Static only (no requests sent)
npx hasura-security --url https://hasura.example.com --no-probeOutput is JSON on stdout (pipe it into CI) and a one-line summary on stderr.
Exit is non-zero only on usage errors — gate your pipeline on the JSON summary.
Install (optional)
npm i -g hasura-security
hasura-security --url https://hasura.example.comZero dependencies. Your data and credentials never leave your machine — every request goes straight from the tool to your Hasura instance.
Sister tools
Same active-probe philosophy for the rest of the backend stack, all MIT:
supabase-security · strapi-security · directus-security · pocketbase-security · firebase-security · appwrite-security · nhost-security · convex-security
License
MIT © Renzo Madueno
