Server-Side Request Forgery (SSRF) is a web security vulnerability that allows an attacker to trick a server into making HTTP requests to unintended locations.
Unlike traditional vulnerabilities, SSRF abuses the trust a server has in its own environment, internal network, or external services. This can lead to data exfiltration, internal service discovery, cloud metadata access, or even remote code execution.
How SSRF Works?
Many web applications allow users to supply a URL that the server fetches. For example:
Image upload where the server downloads an image from a given URL
Webhooks that fetch external data
PDF converters or preview generators
If the application doesn't properly validate the supplied URL, an attacker can manipulate it to force the server into sending requests to arbitrary endpoints.
Red Team Perspective: Exploiting SSRF
Here's a typical red team workflow for exploiting SSRF:
1. Identify User Input that Triggers Server Requests
Example: An image fetch API:
POST /fetchContent-Type: application/json{ "url": "http://example.com/image.png"}
2. Test with a Controlled URL
Supply your own server’s endpoint:
{ "url": "http://attacker.com/test"}
If the server makes a request, you've confirmed SSRF.
3. Probe the Internal Network
Try accessing internal services:
{ "url": "http://127.0.0.1:22"}
If it responds differently, the SSRF allows scanning the internal network.
- Only allow requests to trusted domains or specific URLs. - Reject any user-supplied schemes other than https.
Network Segmentation
- Block the server from accessing internal networks unless required. - Use firewall rules to restrict outbound connections.
Metadata Protection
- Disable direct access to cloud metadata endpoints when possible. -Use instance metadata service v2 (IMDSv2) in AWS.
Use SSRF Mitigations in Frameworks
- Many modern frameworks and proxies provide SSRF protection (e.g., OpenRewrite filters, custom validators).
Monitoring & Detection
- Log all outbound requests from web servers. - Alert on suspicious requests to internal or unexpected IP ranges.
SSRF Practical Demo: Vulnerable App + Exploit
This section provides a hands-on demo for understanding SSRF.
We'll create a vulnerable Flask application and then write a Python exploit script to abuse it.
Vulnerable Flask Application (for Testing Only!)
The following code represents a deliberately vulnerable app.
⚠️ Do not deploy this in production environments! Use only in controlled labs.
# secure_app.pyfrom flask import Flask, request, jsonifyimport requestsfrom urllib.parse import urlparseapp = Flask(__name__)ALLOWED_DOMAINS = ["example.com", "trusted-api.com"]def is_safe_url(url): try: parsed = urlparse(url) if parsed.scheme not in ["http", "https"]: return False domain = parsed.hostname return domain in ALLOWED_DOMAINS except: return False@app.route("/fetch", methods=["POST"])def fetch_url(): data = request.get_json() url = data.get("url") if not is_safe_url(url): return jsonify({"status": "error", "error": "Invalid or blocked URL"}), 400 try: resp = requests.get(url, timeout=3) return jsonify({ "status": "success", "content": resp.text[:200] }) except Exception as e: return jsonify({"status": "error", "error": str(e)}), 500if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)
This version:
Only allows http/https schemes
Restricts requests to trusted domains
Rejects anything else
Conclusion
This article shows:
How easy it is to introduce SSRF with naive code
How an attacker can escalate from external fetches → internal probes → cloud metadata theft
How defensive coding can prevent exploitation
SSRF is a critical vulnerability that often leads to internal network compromise and cloud environment exposure.
By following the red team process, security testers can identify risks, while blue team best practices significantly reduce the attack surface.
SSRF is a reminder that servers should never blindly trust user-supplied input when making requests.