hasura-security

June 21, 2026 · View on GitHub

Audit any self-hosted Hasura GraphQL endpoint for the misconfigurations that actually leak data — GraphQL introspection answered without the admin secret, the anonymous public unauthorized 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.

npm downloads license node deps

$ 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 unauthenticated

Why 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

CheckSeverityHow it's confirmed
No admin secret set at allcriticalanonymous run_sql / export_metadata on /v2/query succeeds
Anonymous public unauthorized rolecriticala bare GraphQL query is answered with no admin secret / Authorization header
Queryable rows leaking via the public rolecriticalanonymous { table(limit:1) } returns rows
Introspection answered without the secrethigh__schema query answered anonymously on /v1/graphql
Console reachable unauthenticatedhighGET /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-probe

Output 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.com

Zero 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


📚 Part of Awesome Backend Security Auditors — the full collection of keyless active-probe auditors.