sast-analysis
Perform codebase analysis and architecture mapping as the first phase of a security assessment. Explores the tech stack,…
Detect GraphQL injection vulnerabilities in a codebase using a three-phase approach: recon (confirm GraphQL usage and find unsafe operation document assembly sites), batched verify (trace user input to those sites in parallel subagents, up to 3 candidate sites each), and merge
Claude Code
$ npx -y skills add utkusen/sast-skills --skill sast-graphql --agent claude-code
Codex
$ npx skills add utkusen/sast-skills --skill sast-graphql -a codex -y
Cursor
$ npx skills add utkusen/sast-skills --skill sast-graphql -a cursor -y
Gemini CLI
$ npx skills add utkusen/sast-skills --skill sast-graphql -a gemini-cli -y
GitHub Copilot
$ npx skills add utkusen/sast-skills --skill sast-graphql -a github-copilot -y
OpenCode
$ npx skills add utkusen/sast-skills --skill sast-graphql -a opencode -y
Windsurf
$ npx skills add utkusen/sast-skills --skill sast-graphql -a windsurf -y
name: sast-graphql description: >- Detect GraphQL injection vulnerabilities in a codebase using a three-phase approach: recon (confirm GraphQL usage and find unsafe operation document assembly sites), batched verify (trace user input to those sites in parallel subagents, up to 3 candidate sites each), and merge (consolidate batch results). Requires sast/architecture.md (run sast-analysis first). Outputs findings to sast/graphql-results.md. If no GraphQL technology is found in Phase 1, later phases are skipped. Use when asked to find GraphQL injection, unsafe GraphQL document construction, or operation string injection bugs.
You are performing a focused security assessment to find GraphQL injection vulnerabilities. This skill uses a three-phase approach with subagents: **recon** (confirm GraphQL usage and find every location where a GraphQL operation document is assembled unsafely), **batched verify** (trace whether user-supplied input reaches those assembly sites, in parallel batches of up to 3 sites each), and **merge** (consolidate batch results into the final report).
**Prerequisites**: `sast/architecture.md` must exist. Run the analysis skill first if it doesn't.
---
GraphQL injection occurs when user-controlled data is embedded into the **GraphQL document** (the query, mutation, or subscription string) rather than passed only through the **variables** map. The parser then interprets attacker-controlled syntax — new fields, aliases, directives, or fragments — which can bypass intent, reach unauthorized resolvers, or change server-side behavior when that document is executed or forwarded.
The core pattern: *unvalidated user input alters the structure or text of the GraphQL operation string passed to `execute`, `graphql`, a gateway client, or an HTTP body `query` field built from string operations.*
Do not flag these as GraphQL injection:
**1. Static operation documents with variables**
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) { name }
}
`;
// execute(schema, GET_USER, null, context, { id: userId });**2. Server uses standard HTTP handler; client sends document; server parses once**
The risk is not the mere presence of `req.body.query` on the server if the server only parses and executes it as the client's operation — injection in *that* path is client-side. Flag **server-side** construction of a **new** document that incorporates user strings before `execute` or before forwarding.
**3. Persisted queries / allowlisted operation IDs**
Document looked up by ID from a server-side registry; client cannot inject arbitrary document text.
**4. graphql-js `Source` with static string; dynamic values only in variableValues**
graphql({ schema, source: staticQueryString, variableValues: { id: userId } });---
// VULNERABLE: user input in operation text
app.post('/proxy', async (req, res) => {
const fragment = req.body.fragment;
const query = `query { me { ${fragment} } }`;
const data = await fetch('https://api.internal/graphql', {
method: 'POST',
body: JSON.stringify({ query }),
});
});
// SECURE: static operation, user data only in variables
const PROXY_QUERY = `query ProxyMe { me { id name email } }`;
app.post('/proxy', async (req, res) => {
const data = await fetch('https://api.internal/graphql', {
method: 'POST',
body: JSON.stringify({ query: PROXY_QUERY }),
});
});# VULNERABLE
def run_custom_query(user_gql: str):
document = f"query {{ user {{ {user_gql} }} }}"
return graphql_sync(schema, document)
# SECURE: validate against allowlist of named operations or use static documents only
ALLOWED = {"id", "name", "email"}
fields = [f for f in requested_fields if f in ALLOWED]
document = "query { user { " + " ".join(ALLOWED.intersection(set(requested_fields))) + " } }"
# BA collection of agent skills that turn your LLM coding assistant into a fully functional SAST scanner to find vulnerabilities in your codebase. Works natively with Claude Code, Codex, Opencode, Cursor and any other assistant that supports agent skills.
Perform codebase analysis and architecture mapping as the first phase of a security assessment. Explores the tech stack,…
Detect business logic vulnerabilities in a codebase using a three-phase approach: threat modeling (domain analysis and attack…
Detect insecure file upload vulnerabilities in a codebase using a three-phase approach: discovery (find all upload sites),…
Detect hardcoded sensitive data (API keys, access tokens, private keys, passwords, etc.) in publicly accessible code — frontend…
Detect Insecure Direct Object Reference (IDOR) vulnerabilities in a codebase using a three-phase approach: recon (find…
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…