July 15, 2026
SSRF in Simple | Server Side Request Forgery | Cybersecurity Lesson
Hi everyone! Today I’m going to explain SSRF (Server-Side Request Forgery) in the simplest way possible so that everyone can understand it.

By Sachin kewat
4 min read
We'll understand the logic behind how SSRF actually happens — from the code to a real SSRF attack, from the backend to the frontend, and from the server to internal requests.
Let's assume you're a pookie developer and you've built an Image Fetch feature in your application.
The application has multiple dropdowns where users can select an image and its name. When they click Fetch, your backend downloads that image from the URL and displays it to the user.
From the user's perspective, it looks like the browser is fetching the image. But in reality, the server is the one making the request.
As a pookie developer, you might write something like this:
url = request.form["image_url"]
response = requests.get(url)url = request.form["image_url"]
response = requests.get(url)Let's understand what these two lines are doing:
request.form["image_url"]→ Takes the URL that the user submitted.requests.get(url)→ The backend sends an HTTP request to that URL and fetches whatever is there.
For example, if the user enters:
https://example.com/image.jpghttps://example.com/image.jpgYour server does this:
User
│
│ https://example.com/image.jpg
▼
Application
│
│ requests.get(url)
▼
example.comUser
│
│ https://example.com/image.jpg
▼
Application
│
│ requests.get(url)
▼
example.comEverything works perfectly because the URL points to a normal public website.
Now here's the important part.
As a developer, you expected users to provide public image URLs, but your code never checks where the URL is pointing. It simply accepts the user's input and tells the server to fetch it.
Now, let's say I capture the request and replace the image URL with an internal URL, for example:
http://127.0.0.1/adminhttp://127.0.0.1/adminWhen I send the modified request, the server makes the request instead of my browser.
Since 127.0.0.1 refers to the server's own localhost, the server tries to access its internal /admin page.
If the application returns the fetched response to me, I may receive the contents of that admin page — even though I could never access it directly from my browser.
This is the basic idea behind Server-Side Request Forgery (SSRF): tricking the server into making requests on your behalf to resources that are normally inaccessible to you.
Now, how can an application be vulnerable to SSRF through AWS Metadata?
Now you might be wondering, why do people always talk about AWS Metadata in SSRF?
Many applications are hosted on cloud providers like AWS. Every AWS EC2 instance has a special Instance Metadata Service (IMDS) that runs on a link-local IP address:
http://169.254.169.254/http://169.254.169.254/This address is not accessible from the Internet. It is intended to be accessed only by the EC2 instance itself to retrieve information such as instance metadata and, depending on the configuration, temporary IAM credentials.
Normally, an attacker cannot directly access this IP.
However, if an application is vulnerable to SSRF and it allows the server to fetch arbitrary URLs, the attacker may try to make the server send a request to the metadata service instead.
The flow looks like this:
Attacker
│
│ URL: http://169.254.169.254/
▼
Vulnerable Application
│
│ requests.get(url)
▼
AWS Instance Metadata Service (IMDS)Attacker
│
│ URL: http://169.254.169.254/
▼
Vulnerable Application
│
│ requests.get(url)
▼
AWS Instance Metadata Service (IMDS)Remember, the attacker is not communicating with the metadata service directly. The server is making the request on the attacker's behalf.
If the application returns the response and the environment is not properly protected, the attacker may be able to obtain metadata or temporary IAM credentials. Those credentials could then be used to access AWS resources that the IAM role is permitted to use.
Note:_ Modern AWS environments often use IMDSv2, which requires a session token before metadata can be accessed. This significantly reduces the risk of straightforward SSRF attacks against the metadata service, although misconfigurations or other application issues can still create SSRF vulnerabilities._
What is IMDSv2, and why does it matter?
Earlier, AWS used IMDSv1 (Instance Metadata Service Version 1).
With IMDSv1, if an application was vulnerable to SSRF, an attacker could simply make the server send a request like:
GET http://169.254.169.254/latest/meta-data/GET http://169.254.169.254/latest/meta-data/Since the request came from the EC2 instance itself, the metadata service would respond with the requested information. This made IMDSv1 a common target during SSRF attacks.
AWS introduced IMDSv2
To reduce this risk, AWS introduced IMDSv2.
Instead of allowing anyone on the instance to directly request metadata, IMDSv2 requires a session token.
The process works like this:
Step 1: Request a token
The application must first send a PUT request to obtain a temporary token.
PUT /latest/api/token HTTP/1.1
Host: 169.254.169.254
X-aws-ec2-metadata-token-ttl-seconds: 21600PUT /latest/api/token HTTP/1.1
Host: 169.254.169.254
X-aws-ec2-metadata-token-ttl-seconds: 21600If the request is valid, AWS returns a token, for example:
AQAEAHh...AQAEAHh...Step 2: Use the token
Now every metadata request must include that token.
GET /latest/meta-data/iam/security-credentials/ HTTP/1.1
Host: 169.254.169.254
X-aws-ec2-metadata-token: AQAEAHh...GET /latest/meta-data/iam/security-credentials/ HTTP/1.1
Host: 169.254.169.254
X-aws-ec2-metadata-token: AQAEAHh...Only then will the metadata service return the requested data.
Why does this help against SSRF?
Many SSRF vulnerabilities only let an attacker make a single GET request to an arbitrary URL.
With IMDSv2, that's no longer enough.
An attacker would first need to:
- Send a PUT request to obtain a token.
- Read the returned token.
- Send another request that includes the token in the
X-aws-ec2-metadata-tokenheader.
If the SSRF vulnerability cannot perform multiple requests, cannot use the PUT method, or cannot add custom headers, the attack against IMDSv2 typically fails.
Is IMDSv2 impossible to exploit?
No.
IMDSv2 is a mitigation, not a guarantee.
If an SSRF vulnerability allows an attacker to:
- Send different HTTP methods (including
PUT), - Add arbitrary headers,
- Read responses, and
- Make multiple requests,
then IMDSv2 may still be reachable.
This is why developers should fix the SSRF vulnerability itself by validating URLs, restricting outbound network access, and allowing requests only to trusted destinations instead of relying solely on IMDSv2.
| Cloud Provider | Metadata IP | Header Required |
| ------------------ | --------------- | -------------------------------------- |
| AWS | 169.254.169.254 | IMDSv2 uses `X-aws-ec2-metadata-token` |
| Microsoft Azure | 169.254.169.254 | `Metadata: true` |
| Google Cloud (GCP) | 169.254.169.254 | `Metadata-Flavor: Google` || Cloud Provider | Metadata IP | Header Required |
| ------------------ | --------------- | -------------------------------------- |
| AWS | 169.254.169.254 | IMDSv2 uses `X-aws-ec2-metadata-token` |
| Microsoft Azure | 169.254.169.254 | `Metadata: true` |
| Google Cloud (GCP) | 169.254.169.254 | `Metadata-Flavor: Google` |Thank you for watching! ❤️
Let's connect on LinkedIn — Sachin Kewat.