agentsclimarketplace

Ssrf prevention

Skill ShieldNet-360/secure-vibe/dist/copilot-skills/.github/skills/ssrf-prevention

Defend against Server-Side Request Forgery: cloud metadata blocking, internal IP filtering, DNS rebinding defense, allowlist-based URL fetching — Applies to: when generating code that fetches a URL supplied by the client; when wiring webhooks, image proxies, PDF renderers, oEmbed fetchers; when running in any cloud environment with an instance metadata service; when reviewing a URL-parsing or HTTP-client wrapperFrom its SKILL.md

Install
npx -y skills add ShieldNet-360/secure-vibe --skill ssrf-prevention

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.0 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it

<!-- Native skill bundle for GitHub Copilot. Generated by `secure-vibe dev regenerate`. --> <!-- Do not edit by hand; the source of truth is skills/ssrf-prevention/SKILL.md. -->

SSRF Prevention

Defend against Server-Side Request Forgery: cloud metadata blocking, internal IP filtering, DNS rebinding defense, allowlist-based URL fetching

ALWAYS

  • Validate every URL fetched on behalf of a client through an allowlist of expected hosts. The allowlist is the only durable defense — block-lists are bypassable through encoding tricks, IPv6 dual-stack, and DNS rebinding.
  • Resolve the hostname once, validate the resolved IP against your block-list of private / reserved / link-local ranges, then connect to that pinned IP using SNI. Otherwise an attacker can race a DNS rebind between validation and connect (time-of-check / time-of-use).
  • Block at the network layer and at the application layer. Drop egress to 169.254.169.254, [fd00:ec2::254], metadata.google.internal, and 100.100.100.200 from any service that doesn't legitimately need the metadata service.
  • Enforce IMDSv2 on AWS EC2 (session-token, hop-limit=1). IMDSv1 — the pattern Capital One's 2019 breach exploited — must be disabled at the instance level.
  • Disable HTTP redirects by default on server-side fetchers (or follow only a small bounded number, re-validating the new URL against the allowlist at each hop). The most common SSRF bypass is https://allowed.example.com returning a 302 to http://169.254.169.254/....
  • Use a separate, restricted HTTP client for user-controlled URLs vs internal URLs. Misusing the wrong client must fail closed (e.g. via type-system distinction in Go / Rust / TypeScript).
  • Parse URLs with a single, well-known parser (Go net/url.Parse, Python urllib.parse, JavaScript new URL()). Differential parsers between e.g. WHATWG and RFC-3986 are a documented SSRF bypass class.

NEVER

  • Trust a hostname / IP that was supplied by the user. Always re-resolve in your trusted resolver and re-check the resolved address.
  • Connect to a URL based on its hostname when the protocol allows redirects — gopher://, dict://, file://, jar://, netdoc://, ldap:// are all common SSRF amplifiers. Restrict to http:// and https:// (and ftp:// only if you actually need it).
  • Trust 0.0.0.0, 127.0.0.1, [::], [::1], localhost, or *.localhost.test — all of them reach the local instance. The list also must include link-local 169.254.0.0/16, IPv4-mapped IPv6 ::ffff:127.0.0.1, and IPv6 ULA fc00::/7.
  • Use the user's URL string in a logging line or an error response — it can be the SSRF reflection oracle that turns blind SSRF into data-exfiltration SSRF.
  • Run a metadata-blocking sidecar / proxy as the only defense — an attacker who finds a Unix-domain-socket pseudo-URL or a misconfigured hostname can route around the proxy. Application-level allowlist remains required.
  • Ship a generic request forwarder that switches to fetching a full, caller-supplied URL when the input "looks absolute" (path.startsWith('http') ? path : base + path). It is a latent SSRF: the day any caller passes user-influenced input, the server fetches an attacker URL — internal hosts and cloud metadata included. Keep the internal-base fetcher and the user-URL fetcher as distinct, type-separated clients.
  • Treat "this endpoint is only reachable from our internal / VPN / allowlisted network" as mitigation for an unsafe server-side fetch. SSRF originates from inside that network, so it reaches exactly the internal services the network control was meant to protect — an IP allowlist is not an authentication boundary against SSRF.
  • Allow IDN / Punycode in user URLs without normalization — IDN homograph attacks bypass naive string-allowlist checks (gооgle.com Cyrillic-o ≠ google.com).

KNOWN FALSE POSITIVES

  • Server-to-server integrations where both sides are operator-controlled and the URL is hard-coded in config (not user-supplied) — the allowlist here is the static config itself.
  • Cluster-local Kubernetes service-to-service calls — these don't go through user input, but be aware of any cross-namespace network policy.
  • Outbound webhooks to the customer (e.g. Slack, Discord, Microsoft Teams webhooks). Validate that the URL host is in the integration's documented allowlist, not arbitrary.
  • A forwarder that uses a hard-coded absolute URL constant (the base is a literal, only a query string or path segment is appended from input) does not change host — the SSRF exists only when the absolute URL itself can be influenced by user input.

What ships with it: 1 file

1.1 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.