Educational demonstration

SSRF Validation and Metadata Exposure in a Link-Preview Service

A string-matching URL filter misses most ways of writing an internal address. Paired with permissive instance settings, that is a path to cloud credentials.

Lab target · not a client engagement
Overview

The lab contains two URL validators for a link-preview feature — a naive string filter and a hardened resolver — plus example Terraform for the instance it would run on. Name resolution and HTTP responses are simulated in the tests; no cloud resources were created.

Findings
high
XV-DEMO-13 · Verified by test

URL filter misses alternate encodings of internal addresses

Description

The filter blocks a few literal strings. Decimal, hex and octal IPv4 forms, IPv4-mapped IPv6, short forms like 127.1, other private ranges, and DNS names that resolve internally all pass.

Impact

The server can be made to request the instance metadata service and internal endpoints.

Recommendation

Parse the URL, resolve the host, reject private/reserved ranges for every resolved address, pin the IP, and re-validate every redirect hop.

high
XV-DEMO-14 · Verified by test

IMDSv2 not required in the launch template

Description

http_tokens = "optional" leaves IMDSv1 available.

Impact

A GET-only SSRF would be enough to read instance role credentials.

Recommendation

Set http_tokens = "required" and keep the hop limit at 1.

medium
XV-DEMO-15 · Verified by test

Instance role grants s3:* on all resources

Description

The IAM policy uses wildcard actions and resources.

Impact

Leaked credentials would expose every bucket rather than the one the service needs.

Recommendation

Scope to the specific bucket and actions the service uses.

Outcome

Measured in the lab: the naive filter allowed 8 of 9 bypass URLs. The hardened validator rejected all 9, allowed a public URL and pinned its address, and refused a redirect from a public page to 169.254.169.254.

A static check flags both configuration issues in vulnerable.tf and none in fixed.tf. The configuration findings were verified by inspection and static checks, not against a live cloud account.

Reproduce

The lab code and tests for this case study live in labs/web2 of the Xevry website repository.

cd labs/web2npm installnode --test test/ssrf.test.js test/terraform.test.js

Files: labs/web2/src/ssrf.js · labs/web2/src/terraformCheck.js · labs/web2/infra/vulnerable.tf · labs/web2/infra/fixed.tf

Start a conversation

Let's discuss your security needs.

Tell us what you're building. We'll respond with clear questions, an honest view of whether we're the right fit, and a scoped proposal if we are.