{"id":51118730,"url":"https://github.com/Perufitlife/convex-security","last_synced_at":"2026-06-25T00:01:25.980Z","repository":{"id":366362796,"uuid":"1275993437","full_name":"Perufitlife/convex-security","owner":"Perufitlife","description":"Anonymously audit a Convex backend for public queries/mutations reachable without auth — proves each leak live via the public HTTP API. Zero-dep Node CLI, MIT.","archived":false,"fork":false,"pushed_at":"2026-06-21T12:49:52.000Z","size":14,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-21T14:40:09.054Z","etag":null,"topics":["access-control","ai-agents","auditor","baas","convex","data-exposure","devsecops","security","security-audit","serverless"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Perufitlife.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-21T12:05:36.000Z","updated_at":"2026-06-21T12:49:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Perufitlife/convex-security","commit_stats":null,"previous_names":["perufitlife/convex-security"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Perufitlife/convex-security","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fconvex-security","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fconvex-security/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fconvex-security/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fconvex-security/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Perufitlife","download_url":"https://codeload.github.com/Perufitlife/convex-security/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fconvex-security/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34753781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access-control","ai-agents","auditor","baas","convex","data-exposure","devsecops","security","security-audit","serverless"],"created_at":"2026-06-25T00:01:24.993Z","updated_at":"2026-06-25T00:01:25.961Z","avatar_url":"https://github.com/Perufitlife.png","language":"JavaScript","funding_links":[],"categories":["BaaS \u0026 Databases"],"sub_categories":[],"readme":"# convex-security\n\n\u003e Audit any **Convex** backend for the mistake that actually leaks data — public queries and mutations reachable **without auth** — and **prove each one live with an anonymous probe**. Convex's own docs warn that public functions \"must have some form of access control\"; this tool calls your public HTTP API the way an attacker would and shows you exactly which functions return real rows to nobody.\n\n\u003e ⚡ **Run it in one line, no deploy key, no install:**\n\u003e ```bash\n\u003e npx convex-security --url https://your-deployment.convex.cloud\n\u003e ```\n\n\u003e 🤝 **Want it done for you?** [Fixed-scope audit — $99 / 24h](https://buy.stripe.com/3cIeVdgikfj47yx9LkcAo0m): I verify each finding live and send a written report with the exact auth-gate fixes.\n\n[![npm](https://img.shields.io/npm/v/convex-security?color=red)](https://www.npmjs.com/package/convex-security) [![downloads](https://img.shields.io/npm/dw/convex-security)](https://www.npmjs.com/package/convex-security) ![license](https://img.shields.io/badge/license-MIT-green) ![node](https://img.shields.io/badge/node-%3E%3D18-blue) ![deps](https://img.shields.io/badge/dependencies-0-brightgreen)\n\n```\n$ npx convex-security --url https://acoustic-dog-123.convex.cloud\n2 critical, 1 high, 0 medium — 3 CONFIRMED via anonymous probe\n  CRITICAL  messages:list   public query — 1,204 rows returned (author, body, email)\n  CRITICAL  messages:send   public mutation — reached past auth, no identity check\n  HIGH      CORS            Origin reflected → cross-site reads of the public API\n```\n\n## Why this exists\n\nConvex is one of the fastest-growing serverless backends in AI/agent app stacks,\nand it ships a footgun that is very easy to miss: **every `query`, `mutation` and\n`action` you export is a public function exposed at a public HTTP endpoint**\n(`POST /api/query`, `/api/mutation`, `/api/action`). Authentication on those\nendpoints is **optional** — a bearer token is attached only if the caller has\none — so any function that forgets to call `ctx.auth.getUserIdentity()` (or\notherwise enforce access control) returns **real data to anyone on the internet**.\n\nConvex's own documentation is explicit that public functions\n[\"must have some form of access control\"](https://docs.convex.dev/functions/query-functions),\nyet this is shipped wrong constantly: a `messages:list` that \"just works\" in the\nbrowser also works for an anonymous `curl`.\n\n`convex-security` checks for these and **confirms the real ones** by issuing the\nexact anonymous request an attacker would — so you triage facts, not maybes.\n\n## What it checks\n\n| Check | Severity | How it's confirmed |\n|---|---|---|\n| Public query reachable without auth | critical | anonymous `POST /api/query` returns `status:\"success\"` with real rows |\n| Public mutation reachable without auth | critical | anonymous `POST /api/mutation` runs past the auth boundary (success or arg-validation error, never a real payload) |\n| CORS reflects arbitrary Origin | high | sends a foreign `Origin`, sees it echoed in `Access-Control-Allow-Origin` |\n| Error messages leak function/table names | medium | calls an unknown path, inspects the error for internal identifiers |\n| Deployment metadata exposed | low | anonymous `GET /version` fingerprints the backend |\n\nMutations are probed with **empty args only** — the tool never sends a real\nwrite payload, so it detects a missing auth gate without mutating your data.\n\n## Usage\n\n```bash\n# Probe a live deployment (guesses common function names)\nnpx convex-security --url https://acoustic-dog-123.convex.cloud\n\n# Learn your exact function names from your local Convex app, then probe\nnpx convex-security --url https://acoustic-dog-123.convex.cloud --discover ./my-app\n\n# Probe specific queries / mutations (\"module:export\" path format)\nnpx convex-security --url https://acoustic-dog-123.convex.cloud --functions messages:list,users:list\nnpx convex-security --url https://acoustic-dog-123.convex.cloud --mutations messages:send\n\n# Write a shareable HTML report\nnpx convex-security --url https://acoustic-dog-123.convex.cloud --html report.html\n\n# Static only (no requests sent)\nnpx convex-security --url https://acoustic-dog-123.convex.cloud --no-probe\n```\n\n`--discover` parses your `convex/` directory for `export const x = query(...)` /\n`mutation(...)` declarations and probes the exact paths your app ships, so you\naudit reality instead of guesses.\n\nOutput is JSON on stdout (pipe it into CI) and a one-line summary on stderr.\nExit is non-zero only on usage errors — gate your pipeline on the JSON `summary`.\n\n## Install (optional)\n\n```bash\nnpm i -g convex-security\nconvex-security --url https://acoustic-dog-123.convex.cloud\n```\n\nZero dependencies. Your data and credentials never leave your machine — every\nrequest goes straight from the tool to your Convex deployment.\n\n## Sister tools\n\nSame active-probe philosophy for the rest of the backend stack, all MIT:\n\n[supabase-security](https://github.com/Perufitlife/supabase-security-skill) ·\n[pocketbase-security](https://github.com/Perufitlife/pocketbase-security-skill) ·\n[firebase-security](https://github.com/Perufitlife/firebase-security-skill) ·\n[appwrite-security](https://github.com/Perufitlife/appwrite-security-skill) ·\n[nhost-security](https://github.com/Perufitlife/nhost-security-skill) ·\n[strapi-security](https://github.com/Perufitlife/strapi-security) ·\n[directus-security](https://github.com/Perufitlife/directus-security)\n\n## License\n\nMIT © [Renzo Madueno](https://github.com/Perufitlife)\n\n---\n\n📚 Part of [**Awesome Backend Security Auditors**](https://github.com/Perufitlife/awesome-backend-security) — the full collection of keyless active-probe auditors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPerufitlife%2Fconvex-security","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPerufitlife%2Fconvex-security","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPerufitlife%2Fconvex-security/lists"}