sast-analysis
Perform codebase analysis and architecture mapping as the first phase of a security assessment. Explores the tech stack,…
Detect Server-Side Request Forgery (SSRF) vulnerabilities in a codebase using a three-phase approach: recon (find outbound call sites), batched verify (trace user input to destinations in parallel subagents, 3 sites each), and merge (consolidate batch results). Requires
Claude Code
$ npx -y skills add utkusen/sast-skills --skill sast-ssrf --agent claude-code
Codex
$ npx skills add utkusen/sast-skills --skill sast-ssrf -a codex -y
Cursor
$ npx skills add utkusen/sast-skills --skill sast-ssrf -a cursor -y
Gemini CLI
$ npx skills add utkusen/sast-skills --skill sast-ssrf -a gemini-cli -y
GitHub Copilot
$ npx skills add utkusen/sast-skills --skill sast-ssrf -a github-copilot -y
OpenCode
$ npx skills add utkusen/sast-skills --skill sast-ssrf -a opencode -y
Windsurf
$ npx skills add utkusen/sast-skills --skill sast-ssrf -a windsurf -y
name: sast-ssrf description: >- Detect Server-Side Request Forgery (SSRF) vulnerabilities in a codebase using a three-phase approach: recon (find outbound call sites), batched verify (trace user input to destinations in parallel subagents, 3 sites each), and merge (consolidate batch results). Requires sast/architecture.md (run sast-analysis first). Outputs findings to sast/ssrf-results.md. Use when asked to find SSRF or server-side request forgery bugs.
You are performing a focused security assessment to find SSRF vulnerabilities in a codebase. This skill uses a three-phase approach with subagents: **recon** (find all places that make outbound TCP, DNS, or HTTP requests), **batched verify** (trace whether user-supplied input reaches those call sites, in parallel batches of 3), and **merge** (consolidate batch reports into one file).
**Prerequisites**: `sast/architecture.md` must exist. Run the analysis skill first if it doesn't.
---
SSRF occurs when an attacker can cause the server to make outbound network requests to an arbitrary destination — including internal services, cloud metadata endpoints, or other external targets — by supplying or influencing the URL, hostname, IP, or port used in a server-side request.
The core pattern: *unvalidated, user-controlled input reaches the destination argument of an outbound network call.*
Do not flag these:
When you see these patterns, the code is likely **not vulnerable**:
**1. Strict allowlist of permitted destinations**
ALLOWED_HOSTS = {"api.example.com", "cdn.example.com"}
parsed = urlparse(user_url)
if parsed.hostname not in ALLOWED_HOSTS:
raise ValueError("Destination not allowed")
requests.get(user_url)**2. Allowlist of permitted URL prefixes / schemes**
ALLOWED_PREFIXES = ["https://api.example.com/", "https://cdn.example.com/"]
if not any(user_url.startswith(p) for p in ALLOWED_PREFIXES):
abort(400)
requests.get(user_url)**3. No user influence on the destination**
# Destination fully hardcoded — no user input involved
response = requests.get("https://api.thirdparty.com/data")> **Note**: IP blocklists (blocking 169.254.0.0/16, 10.0.0.0/8, etc.) are **not** sufficient protection — they can be bypassed via DNS rebinding, URL encoding, IPv6 notation, decimal IP representation, or redirect chains. Do not treat a blocklist as making a site safe; classify it as Likely Vulnerable.
---
# VULNERABLE: URL fully controlled by user
@app.route('/fetch')
def fetch():
url = request.args.get('url')
response = requests.get(url)
return response.text
# SECURE: strict allowlist on destination host
ALLOWED = {"api.example.com"}
@app.route('/fetch')
def fetch():
url = request.args.get('url')
if urlparse(url).hostname not in ALLOWED:
abort(403)
response = requests.get(url)
return response.text# VULNERABLE: user controls the URL passed to urlopen
def preview(request):
target = request.GET.get('target')
data = urllib.request.urlopen(target).read()
return HttpResponse(data)
# SECURE: only allow https scheme to a hardcoded host
def preview(request):
target = request.GET.get('target')
parsed = urlparse(target)
if parsed.scheme != 'https' or parsed.hostname != 'media.example.com':
return HttpResponse(status=400)
data = urllib.request.urlopen(target).read()
return HttpResponse(data)// VULNERABLE: webhook URL comes directly from request body
app.post('/webhook/test', async (req, res) => {
const { url } = req.body;
const result = await fetch(url);
res.json(await result.json());
});
// SECURE: allowlist check before fetch
const ALLOWED_HOSTS = new Set(['hooks.example.com']);
app.post('/webhook/test', async (req, res) => {
const { url } = req.body;
const { hostname } = new URL(url);
if (!ALLOWED_HOSTS.has(hostname)) return res.status(403).send('Forbidden');
const result = await fetch(url);
res.json(await result.json());
});// VULNERABLE: host and path from query string
app.get('/proxy', (req, res) => {
const { host, path } = req.query;
http.get({ host, path }, (proxyRes) => proxyRes.pipe(res));
});# VULNERABLE: open() fetches arbitrary URL def import url = params[:url] content = URI.open(url).read # also triggers for open(url) via Kernel#open # ... end # SECURE: restrict scheme and host def import url = params[:url] uri = URI.parse(url) raise "Forbidden" unless uri.is_a?(URI:
A 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 GraphQL injection vulnerabilities in a codebase using a three-phase approach: recon (confirm GraphQL usage and find unsafe…
Detect hardcoded sensitive data (API keys, access tokens, private keys, passwords, etc.) in publicly accessible code — frontend…
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…