sast-analysis
Perform codebase analysis and architecture mapping as the first phase of a security assessment. Explores the tech stack, frameworks, entry points, data flows,…
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
$ npx -y skills add utkusen/sast-skills --skill sast-ssrf --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/sast-ssrfContext preview
The summary Claude sees to decide when to auto-load this skill.
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
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.
Repo: utkusen/sast-skills
Perform codebase analysis and architecture mapping as the first phase of a security assessment. Explores the tech stack, frameworks, entry points, data flows,…
Detect business logic vulnerabilities in a codebase using a three-phase approach: threat modeling (domain analysis and attack scenarios), batched verify (check…
Detect insecure file upload vulnerabilities in a codebase using a three-phase approach: discovery (find all upload sites), batched verify (check extension…
Detect GraphQL injection vulnerabilities in a codebase using a three-phase approach: recon (confirm GraphQL usage and find unsafe operation document assembly…
Detect hardcoded sensitive data (API keys, access tokens, private keys, passwords, etc.) in publicly accessible code — frontend JavaScript, mobile apps,…