Lesson 3 of 4 · 25 min

Design a server-side fetcher with bounded reach

Prevent untrusted URLs from granting internal network authority.

Mechanism and reasoning

A server-side fetcher turns a user's URL into a request from the server's network position. That server may reach destinations the user cannot. The trust boundary is therefore about delegated network authority, not just whether a string looks like a URL.
If the feature needs a known set of destinations, an allow-list can be simpler to reason about than accepting arbitrary URLs. Match the parsed and normalized destination under a defined policy. Restrict schemes and ports, and decide whether redirects are allowed. A valid initial host can redirect to a prohibited destination.
Address validation has timing and parsing concerns. DNS can resolve to multiple addresses, including private or loopback ranges. The address used for the actual connection must remain within policy. Validating one resolution and then allowing a library to resolve again can create a gap. Use a well-tested fetch component and network controls rather than inventing a fragile regular expression.
Network egress restrictions add defense if application validation fails. They should block access to internal management endpoints and other prohibited destinations while permitting the required feature. This is not a reason to omit application-level URL policy. Both layers need tests.
Bound response size, duration and resource use. Even a permitted external destination can serve an enormous file or keep the connection open. A security review should include availability and data handling, not only internal-address access. Use an isolated test server with invented addresses and responses for exercises; no real internal service probing is required.

Fetch policy case

Teaching product creates previews for links from three approved documentation domains. It does not need arbitrary internet access. The simplest contract is HTTPS on port 443 for those exact approved hostnames, with a limited redirect policy and a maximum response size. The server returns extracted title and summary, not the raw response headers or arbitrary content.
StageCheckFailure response
ParseOne supported URL parser; HTTPS schemeReject unsupported or malformed input
Host policyExact approved host under normalization rulesReject outside the feature's allowed set
Resolve/connectAll used addresses satisfy destination policyDo not connect to prohibited ranges
RedirectReapply policy at every permitted hopStop on prohibited target or hop limit
ReadSize, timeout and content-type limitsAbort boundedly and return a safe error
ReturnExtract intended fields onlyDo not expose internal response details
The host allow-list is not a suffix string check that accepts anything ending in similar text. A hostname such as approved.example.attacker.test is not approved.example. Normalize case and internationalized forms under the parser's rules and compare the intended host identity. Avoid giving learners a collection of bypass payloads to memorize. The durable skill is reasoning about the parser, resolver and connection destination.

Redirect trace

A permitted documentation URL returns a redirect to an internal management address. If the HTTP client follows redirects automatically after the first URL was checked, the server can cross the boundary. The correct policy either disables redirects or validates each new destination with the same constraints. A maximum hop count prevents loops but does not authorize a prohibited hop.
A second trace uses a permitted-looking hostname whose resolution changes. The application checks an allowed public address, but a later resolution used by the connection returns a private address. The exact mitigation depends on the client and environment. The design must bind destination validation to the address actually used and maintain correct TLS hostname validation. Simply connecting by address while disabling TLS checks can trade one flaw for another.

Availability case

An approved host serves a response that never ends. A connection timeout alone may limit establishment but not the entire read. Define total request duration, idle-read behavior and maximum bytes. A preview only needs a small amount of text, so the contract can stop after a bounded body. Decompression can expand data substantially; apply limits at the stage that represents actual resource consumption.
The feature also needs concurrency limits. One user submitting thousands of valid approved URLs can exhaust outbound sockets or worker memory. Apply per-user and global limits, and ensure cancellation releases resources. These are availability controls under the same delegated-work model.

Verification plan

Use a local fake HTTP service in a disposable environment. It can return a normal page, a redirect, a slow body and an oversized body. Replace DNS or the connector through a test seam so the exercise can simulate allowed and prohibited addresses without touching a real metadata endpoint. Verify that prohibited destinations are never contacted, not merely that the final response is hidden.
A useful test records connection attempts. If the fetcher contacts an internal address and then returns 'blocked,' the data may already have been exposed or a side effect may have occurred. Enforcement must precede the prohibited connection. Similarly, a response-size test should observe bounded memory and connection closure, not just an error string.
The interview answer should identify the smallest authority the feature needs. A three-domain preview service does not need a general-purpose internal HTTP proxy. If the product later expands to arbitrary user websites, revisit the threat model and isolation strategy. Do not silently stretch the original allow-list design beyond its assumptions.

Worked example

Teaching redirect trace: request R1 targets an approved HTTPS documentation host. Hop 1 returns a 302 to an unapproved host. Under a policy that rechecks every hop, R1 stops before making the second connection. The result is a safe preview failure with a policy reason. A test spy records one outbound connection, not two. If the client followed the second hop and only then filtered the response, the security boundary was already crossed.

Exercise

A preview client validates the first URL, follows redirects automatically, has a five-second connect timeout and no body-size limit. Identify three missing controls and a local test for one of them.

Model solution and rubric

It needs redirect destination revalidation or redirects disabled, a total/read deadline and a response-size limit. Depending on its destination policy, it also needs address-use validation and egress controls. Test with a local server that redirects to a fake prohibited destination and assert no connection attempt to that destination. Test oversized and slow bodies separately. A connect timeout does not bound a body streamed after connection.
Score out of four: one point for the correct result, one for showing the intermediate reasoning, one for identifying the stated failure case, and one for a verification that could disprove the answer. Do not award the reasoning point for a tool name alone.

Failure modes and misconceptions

Misconception 1: a URL that passes a regular expression is safe to fetch. Parsing, resolution, redirects and actual connection addresses can differ. Misconception 2: hiding the response after fetching prevents SSRF. The prohibited request itself can disclose data or cause effects, so enforcement must occur before connection.

Interview probe

Evidence class: recommended. Original practice.
How would you secure a link-preview endpoint that only needs three known domains?
Strong answer: I would restrict the feature to those parsed HTTPS hosts and ports, validate actual destinations and each allowed redirect, add egress restrictions and bound time, bytes and concurrency. I would test connection attempts with local fake services.
Follow-up: What changes when the product accepts arbitrary external websites?
Weak answer indicators: String suffix checks alone; automatic redirects after one validation; disabling TLS identity checks; only a connect timeout.

Sources

Technical references: OWASP SSRF prevention; OWASP threat modeling. Sources support the documented mechanisms. The numbers, decisions, rubrics and interview prompts in this lesson are original teaching examples, not measurements or employer question claims.
docsOWASP SSRF preventioncheatsheetseries.owasp.orgdocsOWASP threat modelingcheatsheetseries.owasp.org

Checkpoint

An allowed URL redirects to a prohibited destination. Which behavior preserves the boundary?

ATrust the initial host for the entire chainBRevalidate each destination before connection or disable redirectsCConnect but suppress the returned bodyDPermit it if the chain has fewer than three hops
Sign up free to answer and see why

Checkpoint

The connection opens promptly but the server streams an endless body. Which bound is missing?

AOnly a shorter DNS cache lifetimeBOnly a stricter hostname suffix testCA total/read deadline and response-size limitDOnly a lower redirect count
Sign up free to answer and see why

Checkpoint

The fetcher contacts an internal address and then reports blocked. What does the test show?

ASuccess because the body was hiddenBSuccess if no exception escapedCOnly a missing error codeDDestination enforcement occurred too late
Sign up free to answer and see why

Checkpoint

The feature needs only three known HTTPS domains. Which design best matches its authority?

AA parsed host/port allow-list with destination checks and restricted egressBA general internal proxy limited only by user loginCAny public hostname with unrestricted redirectsDA suffix check with DNS validation omitted
Sign up free to answer and see why

Checkpoint

DNS validation sees a public address, but the later connection resolves a private address. What must be preserved?

AOnly the original URL string in logsBThe relationship between validated destination and actual connection, with TLS identity checksCOnly the certificate's remaining lifetimeDOnly a fixed response MIME type
Sign up free to answer and see why

Explain how you would prevent untrusted urls from granting internal network authority without reading the solution. State one assumption that could change your answer, and one observation that would make you revise it.

Not yetGetting thereConfident

Wrap-up

  • Authorize the destination actually contacted, at every hop, and bound the delegated work. Test that prohibited connections never occur.

Sources

Free to read · better with Enzo

Learn it with Enzo

Save your progress, answer the checkpoints, and let Enzo quiz you on what you just read.