# Graphql Security

> Defend GraphQL APIs: depth/complexity limits, introspection in production, batching/aliasing abuse, field-level authorization, persisted queries — Applies to: when generating GraphQL schemas, resolvers, or server config; when wiring authentication/authorization to a GraphQL endpoint; when adding a public GraphQL API gateway; when reviewing /graphql endpoint exposure

- **Type:** Skill
- **Install:** `agentstack add skill-shieldnet-360-secure-vibe-graphql-security`
- **Verified:** Pending review
- **Seller:** [ShieldNet-360](https://agentstack.voostack.com/s/shieldnet-360)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ShieldNet-360](https://github.com/ShieldNet-360)
- **Source:** https://github.com/ShieldNet-360/secure-vibe/tree/main/dist/claude-skills/.claude/skills/graphql-security

## Install

```sh
agentstack add skill-shieldnet-360-secure-vibe-graphql-security
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# GraphQL Security

Defend GraphQL APIs: depth/complexity limits, introspection in production, batching/aliasing abuse, field-level authorization, persisted queries

## ALWAYS

- Enforce a maximum **query depth** (typical: 7–10) and **query complexity** (cost) at the server. A 5-level nested query against a many-to-many relationship can return billions of nodes; without a cost limit, one client crashes the database.
- Disable **introspection** in production. Introspection makes reconnaissance trivial; legitimate clients have the schema baked in via codegen or a `.graphql` artifact.
- Use **persisted queries** (allowlisted operation hashes) for any high-traffic / public API. Anonymous arbitrary GraphQL is the GraphQL equivalent of `eval(req.body)`.
- Apply **field-level authorization** in resolvers, not just at the endpoint. GraphQL aggregates many fields into one HTTP response — a single missing `@auth` on a sensitive field leaks data across the whole query.
- Limit the number of **aliases** per request (typical: 15) and the number of **operations per batch** (typical: 5). Apollo / Relay both allow batched queries — without limits this is an N-pages-of-the-API amplification primitive.
- Reject **circular fragment** definitions early (most servers do, but custom executors don't). A self-referencing fragment causes exponential parse-time cost.
- Return generic errors to clients (`INTERNAL_SERVER_ERROR`, `UNAUTHORIZED`) and route stack traces / SQL snippets to server logs only. Default Apollo errors leak schema and query internals.
- Set a request size limit (typical: 100 KiB) and a request timeout (typical: 10 s) on the HTTP layer in front of the GraphQL server. A 1 MiB GraphQL query has no legitimate use.

## NEVER

- Expose `/graphql` introspection on a production endpoint. The GraphQL playground (GraphiQL, Apollo Sandbox) must also be disabled in production builds.
- Trust the depth / complexity of a query because "our clients only send well-formed queries." Any attacker can hand-craft a request to `/graphql`.
- Allow `@skip(if: ...)` / `@include(if: ...)` directives to gate authorization checks. Directives run after authorization in most executors, but custom directive ordering has produced authz bypasses.
- Implement N+1 patterns in resolvers (one DB query per parent record). Use a DataLoader or join-based fetch. N+1 is both a performance bug and a DoS amplifier.
- Allow file uploads via GraphQL multipart (`apollo-upload-server`, `graphql-upload`) without size limits, MIME validation, and out-of-band virus scan. The 2020 CVE-2020-7754 (`graphql-upload`) showed how a malformed multipart can crash the server.
- Cache GraphQL responses by URL alone. POST `/graphql` always uses the same URL; cache must key on operation hash + variables + auth claims to avoid cross-tenant leaks.
- Expose mutations that take untrusted JSON `input:` objects without schema validation. GraphQL types are mandatory at the schema layer, but `JSON` / `Scalar` types bypass them entirely.

## KNOWN FALSE POSITIVES

- Internal admin GraphQL endpoints behind an authenticated VPN may legitimately leave introspection on for developer ergonomics.
- Static-allowlisted persisted queries make depth / complexity checks redundant on those operations — keep the checks for any operation that isn't in the allowlist (i.e. operations through a `disabled` flag).
- Public, read-only data APIs may use very high cost limits with caching aggressively configured at the CDN layer; the trade-off is documented per endpoint.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ShieldNet-360](https://github.com/ShieldNet-360)
- **Source:** [ShieldNet-360/secure-vibe](https://github.com/ShieldNet-360/secure-vibe)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** yes

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-shieldnet-360-secure-vibe-graphql-security
- Seller: https://agentstack.voostack.com/s/shieldnet-360
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
