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.
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.
highXV-DEMO-13 · Verified by testURL filter misses alternate encodings of internal addresses
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.
highXV-DEMO-14 · Verified by testIMDSv2 not required in the launch template
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.
mediumXV-DEMO-15 · Verified by testInstance role grants s3:* on all resources
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.
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.
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.jsFiles: labs/web2/src/ssrf.js · labs/web2/src/terraformCheck.js · labs/web2/infra/vulnerable.tf · labs/web2/infra/fixed.tf
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.