Course outline

Web Security / Intermediate: browser and data interpretation defenses / Lesson 12

SSRF and server-side outbound boundaries

Constrain server-initiated retrieval through destination policy, supported clients, network controls, and bounded responses.

About 4 min readContent reviewed
On this page

Lesson goals

  • Distinguish parsing an allowed URL from safely connecting to a destination.
  • Review redirects, DNS, credentials, and response use without real requests.

Recognize the authority of a server-side fetch

A feature that imports an image, previews a link, or calls a callback can cause the server to connect using its own network reach and credentials. That is a separate trust boundary from a browser opening the same URL. Prefer a small set of known destinations or an application-owned resource identifier when the product permits it. Do not offer an unrestricted URL relay merely because the user is authenticated. Name the required protocol, host, path purpose, data returned, and owner. This course performs local parsing only and makes no outbound request, DNS lookup, or connection to any target.

Classify a declared origin without fetching it

The standalone helper maps one approved synthetic HTTPS origin to a local destination category. It rejects embedded user information and fragments for this fictional feature. A successful classification is not a complete SSRF defense: it does not validate resolved addresses, redirect behavior, connection reuse, proxy configuration, or response content. Browser-style URL parsing helps normalize syntax, but the chosen HTTP client can have its own interpretation rules. Keep the validated representation tied to what the client actually uses. Product-specific path and resource constraints remain necessary even within an approved origin.

javascript A complete offline destination-classification fixture
function destinationCategory(value) {
  if (typeof value !== "string") return null
  try {
    const url = new URL(value)
    if (url.protocol !== "https:" || url.username || url.password || url.hash) return null
    const approved = new Map([["https://media.example.invalid", "approved-media"]])
    return approved.get(url.origin) ?? null
  } catch {
    return null
  }
}
if (destinationCategory("https://media.example.invalid/cover") !== "approved-media") {
  throw new Error("DESTINATION_CATEGORY_MISMATCH")
}
if (destinationCategory("https://other.example.invalid/cover") !== null) {
  throw new Error("UNAPPROVED_ORIGIN_ACCEPTED")
}

Uses Node’s local URL parser and reserved fictional domains. It never fetches either URL. The assertions establish a narrow origin-category mapping, not safe server connectivity or protection of internal resources.

Review the actual connection path

Destination validation must account for DNS resolution and the addresses the approved client ultimately connects to. A name reviewed once does not automatically establish every later connection’s destination. Redirects can change the target, so disable unnecessary redirects or apply the reviewed policy to every allowed hop under supported client behavior. Network egress controls can limit reach to sensitive internal and administrative resources and complement application validation. Do not forward ambient credentials, cookies, or authorization headers to arbitrary destinations. These decisions require the actual platform’s documented network and client semantics; a string allowlist alone cannot enforce them.

Specify bounded retrieval and response handling

The synthetic plan records separate checks for destination, transport, identity, response limits, and content use. It is not a firewall rule, proxy configuration, or a request to a cloud metadata endpoint. Bound connection duration, total response bytes, decompression or parsing work, and concurrency according to the service. Validate content before storing or rendering it, and avoid returning private server responses through a public preview. Failure should not trigger uncontrolled retries or reveal internal addresses and credentials in user errors. Keep the outbound service’s authority as narrow as its purpose.

json A non-operational outbound-retrieval plan
{
  "feature": "synthetic-cover-import",
  "destination": "approved-category-only",
  "resolutionAndConnection": "reviewed-platform-control",
  "redirects": "not-needed-by-this-feature",
  "ambientCredentials": "not-forwarded",
  "responsePolicy": ["bounded-duration", "bounded-size", "validated-content"],
  "operationalState": "plan-only"
}

The file creates no egress rule and contacts no service. Each named control requires implementation evidence on the actual platform. Reserved labels and example domains do not identify a real target or credential source.

Verify the client and network boundary safely

Use an authorized isolated harness with fake resolution and transport to test approved destinations, policy refusal, redirects, timeout, and oversized or invalid responses. Do not scan a real network or request internal endpoints to prove a lesson. Verify that the actual client uses the validated destination representation and that errors and logs omit secrets. Review queues and cleanup for imported content. Maintain the policy when suppliers, endpoints, or network architecture change. The defensive result is a constrained service capability with clear evidence, not a claim that one URL parser secures every server-side fetch.

Common errors and fixes

An allowed hostname is called a complete SSRF defense

Why it happens
Parsing is confused with resolution and connection control.
How to fix it
Review the supported client, redirects, resolved destinations, and egress boundary.
Prevent it next time
State every unverified connection assumption.

A preview forwards privileged credentials

Why it happens
Ambient server authority is reused for an untrusted destination.
How to fix it
Remove unnecessary authority through the approved service design.
Prevent it next time
Review outbound identity and destination together.

A small input URL causes unbounded processing

Why it happens
Response and decompression costs were omitted.
How to fix it
Apply reviewed response, duration, and processing limits.
Prevent it next time
Test controlled oversized and timeout fixtures offline.

Check your understanding

1. Why does the local URL classifier not prove DNS safety?

Show worked solution

It never resolves a name or observes the address used by a client. Those behaviors belong to a separate platform and connection boundary, including redirects and changing results. Verify them with approved mocks and actual integration evidence where authorized.

2. A feature only needs one supplier’s media. Should it accept every URL?

Show worked solution

A narrow approved destination or resource-id contract is easier to constrain than a general relay. Review paths, transport, response limits, credentials, and supplier changes rather than granting the server’s network reach to arbitrary user input.

Key takeaways

  • Server retrieval spends server authority.
  • Parsing, DNS, redirects, and egress are separate boundaries.
  • Bound responses and keep credentials out of arbitrary requests.

Official references