Web › Module 4 › Lesson 5
Lab — SSRF Lab
Build a tiny URL fetcher locally, demonstrate SSRF to localhost, then add defenses—ethical lab only
Opening
Fetch a URL—then fetch trouble
You will run a minimal vulnerable web app on your machine, trigger SSRF against a local secret endpoint, and then patch the allowlist. Use 127.0.0.1 only—never aim SSRF payloads at third-party sites or cloud metadata you do not own.
1. Step 1 — Vulnerable fetch app
ssrf_lab.py — save and run locallyfrom flask import Flask, request import requests app = Flask(__name__) SECRET = "cyberlium-local-secret" @app.get("/secret") def secret(): return SECRET @app.get("/fetch") def fetch(): url = request.args.get("url", "") r = requests.get(url, timeout=3) return r.text[:500] if __name__ == "__main__": app.run(port=5050)
from flask import Flask, request
import requests
app = Flask(__name__)
SECRET = "cyberlium-local-secret"
@app.get("/secret")
def secret():
return SECRET
@app.get("/fetch")
def fetch():
url = request.args.get("url", "")
r = requests.get(url, timeout=3)
return r.text[:500]
if __name__ == "__main__":
app.run(port=5050)2. Step 2 — Trigger SSRF
Request internal secret via fetch (same machine)curl "http://127.0.0.1:5050/fetch?url=http://127.0.0.1:5050/secret"
curl "http://127.0.0.1:5050/fetch?url=http://127.0.0.1:5050/secret"
You should see the secret string in the response—proving the server accessed an internal URL you chose. Note how the browser never talked to /secret directly; the server did.
3. Step 3 — Add a basic allowlist
Patch idea — block loopback and private rangesfrom urllib.parse import urlparse import ipaddress, socket def safe_host(url): host = urlparse(url).hostname ip = ipaddress.ip_address(socket.gethostbyname(host)) if ip.is_private or ip.is_loopback: raise ValueError("blocked") return url
from urllib.parse import urlparse
import ipaddress, socket
def safe_host(url):
host = urlparse(url).hostname
ip = ipaddress.ip_address(socket.gethostbyname(host))
if ip.is_private or ip.is_loopback:
raise ValueError("blocked")
return urlComplete SSRF lab
Run ssrf_lab.py, retrieve /secret through /fetch, then implement at least one defense (allowlist or private IP block) and confirm the bypass no longer works.
Knowledge Check
In this lab, SSRF succeeded because:
Multiple choice
Knowledge Check
True or False: Blocking private and loopback IPs in outbound fetchers is a valid SSRF mitigation.
True or False