From soundcheck
Detects SSRF vulnerabilities in HTTP requests from user URLs, proxies, webhooks, and URL previews. Flags risks and suggests fixes with scheme/host/IP checks and redirect handling.
npx claudepluginhub thejefflarson/soundcheck --plugin soundcheckThis skill uses the workspace's default tool permissions.
Protects against Server-Side Request Forgery where an attacker tricks the server into
Detects Server-Side Request Forgery (SSRF) vulnerabilities where user-controlled URLs access internal services, cloud metadata, or bypass networks in JS/TS, Python, Go, Ruby code. Audits webhooks, URL previews, imports.
Audits Python code for SSRF (CWE-918) vulnerabilities in HTTP clients (requests, httpx, urllib, aiohttp), webhooks, proxies, file/model downloads, and SVG/XML external resources.
Analyzes PHP code for SSRF vulnerabilities. Detects unvalidated URLs, internal network access, DNS rebinding, cloud metadata access, URL parsing bypasses. Use for PHP web app security audits.
Share bugs, ideas, or general feedback.
Protects against Server-Side Request Forgery where an attacker tricks the server into making requests to internal services, cloud metadata endpoints, or arbitrary external hosts. Exploitation leads to internal network scanning, credential theft from cloud metadata APIs (169.254.169.254), and access to services behind firewalls.
requests.get(user_url) — fetches any URL the caller supplies, including http://169.254.169.254/http.Get(fmt.Sprintf("http://%s/api", userHost)) — host from user input reaches outbound requestfetch(req.body.webhookUrl) — webhook callback to attacker-controlled or internal addressnew URL(input).openStream() — Java URL fetch with no host validation, follows redirects to internal IPsHttpClient.send(HttpRequest.newBuilder().uri(URI.create(userInput)).build()) — unchecked URIFlag the vulnerable code and explain the risk. Then suggest a fix that establishes
these properties. Proxy, webhook, and URL-preview features are the highest-risk
shapes — the scheme/host/IP/redirect checks must actually run at the call site
before the outbound request; a comment saying "URL should be validated" or
principles repeated in prose do not satisfy anything if the code just calls
http.Get(userURL).
https (and maybe http for trusted internal use).
Reject file:, gopher:, ftp:, dict:, and other schemes that SSRF toolkits
exploit.10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16
and IPv6 ::1/128, fc00::/7, fe80::/10. Resolve-then-check catches DNS
rebinding; an allowlisted hostname can still resolve to 169.254.169.254.
Language-idiomatic checks that cover the same ranges (Java
isLinkLocalAddress() + isSiteLocalAddress(); Go IsLinkLocalUnicast() + IsPrivate()) are equivalent to the explicit CIDR form.Anchor — shape, not implementation:
u = parse(url)
require(u.scheme in ALLOWED_SCHEMES)
require(u.host in ALLOWED_HOSTS)
require(resolve(u.host) not in BLOCKED_NETS) # defeats DNS rebinding
fetch(u, follow_redirects=False) # or re-validate each hop
169.254.0.0/16, fe80::/10, and fc00::/7, or via language-idiomatic checks that cover the same ranges. Declaring a list without evaluating it does not satisfy this