Listen to this Post

Introduction:
Server-Side Request Forgery (SSRF) remains one of the most dangerous web vulnerabilities, allowing attackers to pivot from public-facing servers to internal networks, cloud metadata endpoints, and otherwise protected services. Microsoft has released two game-changing tools – AntiSSRF (a secure-by-default library for .NET and Node.js) and Dusseldorf (a dynamic OAST testing tool) – that shift defense from fragile input validation to a resilient runtime agent architecture.
Learning Objectives:
- Understand why traditional URL validation fails against modern SSRF bypass techniques (IPv6 mapping, decimal IP, DNS rebinding, redirects).
- Learn to implement AntiSSRF in .NET and Node.js applications to enforce secure outgoing requests.
- Use Dusseldorf to actively test SSRF mitigations and simulate out-of-band attack scenarios.
You Should Know:
- The Runtime Agent Advantage – Beyond Static URL Parsing
Traditional SSRF defenses rely on blocklists or regex to validate URLs before making requests. Attackers constantly find new encodings: `http://[::ffff:127.0.0.1]`, `http://0x7f000001`, or even `http://2130706433` (decimal). Microsoft’s AntiSSRF solves this by treating all URL inputs as untrusted and rejecting unsafe values during concatenation, plus a runtime agent that intercepts outgoing traffic after DNS resolution. This catches DNS rebinding and redirects that bypass initial checks.
Step‑by‑step guide to understanding the runtime check:
- Application code calls a request method (e.g.,
http.get(url)).
2. AntiSSRF’s interceptor runs before the TCP connection.
3. It resolves the hostname to IP addresses.
- It compares each IP against private ranges (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,169.254.0.0/16,::1,fc00::/7). - If any resolved IP is private or link‑local, the request is blocked.
- For .NET, you can configure custom allowed ranges or block additional ranges via configuration.
Example configuration (appsettings.json for .NET):
{
"AntiSSRF": {
"AllowedRanges": [ "192.0.2.0/24" ],
"BlockRanges": [ "10.0.0.0/8" ]
}
}
Windows / Linux commands to test private IP reachability (for understanding):
Linux - check if IP is private
ipcalc 10.0.0.1 | grep Private
Windows PowerShell
[System.Net.IPAddress]"10.0.0.1" -as [System.Net.IPAddress] | % { $_.AddressFamily }
Test DNS rebinding simulation (using dig)
dig +short example.com
while true; do dig +short rebind.example.com; sleep 1; done
2. Implementing AntiSSRF in .NET 6+
Microsoft’s library integrates into `HttpClient` via a custom message handler. It works with all outgoing HTTP requests.
Step‑by‑step installation and usage:
1. Add NuGet package:
`dotnet add package Microsoft.Security.AntiSSRF`
2. Register the handler in `Program.cs`:
using Microsoft.Security.AntiSSRF;
builder.Services.AddHttpClient("secureClient")
.AddHttpMessageHandler<AntiSSRFHandler>();
3. Use the named client:
var client = factory.CreateClient("secureClient");
// This request will be blocked if the resolved IP is private
var response = await client.GetAsync("http://169.254.169.254/latest/meta-data/");
4. For global protection, replace default `IHttpClientFactory` or use a delegating handler in pipeline.
Advanced: Customizing block rules for cloud metadata endpoints
var options = new AntiSSRFOptions
{
BlockPrivateRanges = true,
AdditionalBlockedIPs = { "169.254.169.254", "fd00:ec2::254" }
};
services.AddSingleton(options);
3. Node.js Integration – Secure Your Backend APIs
The Node.js version wraps `axios` and node-fetch, intercepting requests before they leave the event loop.
Step‑by‑step setup:
1. Install package:
`npm install @microsoft/antissrf`
2. Wrap your HTTP client:
const { createSecureClient } = require('@microsoft/antissrf');
const client = createSecureClient();
// This will throw an error if destination is private
try {
await client.get('http://127.0.0.1:8080/admin');
} catch (err) {
console.log('SSRF prevented:', err.message);
}
3. Configure allowlist for legitimate internal APIs (e.g., a known internal service):
const client = createSecureClient({
allowedRanges: ['10.88.0.0/16'] // your internal microservice subnet
});
Testing the protection locally (Linux command to simulate an internal service):
Create a mock metadata server sudo python3 -m http.server 80 --bind 169.254.169.254 Then run your Node.js app – the request will be blocked.
4. Dusseldorf – Dynamic SSRF Testing Made Easy
Dusseldorf is an OAST (Out‑of‑Band Application Security Testing) tool that verifies your SSRF defenses. It acts as a collapsible server: you inject a payload, and Dusseldorf tells you if the target server made a request to a private or external address.
Step‑by‑step Dusseldorf workflow:
- Download Dusseldorf from its GitHub (linked in post). It’s a single Go binary.
git clone https://github.com/microsoft/dusseldorf cd dusseldorf go build -o dusseldorf main.go
- Run the listener (publicly accessible or via tunneling):
./dusseldorf server --port 8080 --callback-url https://your-callback-server.com
- Generate a payload (e.g., a URL that points to your Dusseldorf server):
./dusseldorf payload --type url --domain your-dusseldorf-server.com Example output: http://your-dusseldorf-server.com:8080/ssrf-test-xyz
- Inject the payload into your application (e.g., as a user‑controlled URL parameter).
- Check for callbacks – Dusseldorf logs any outbound request to its domain, indicating an SSRF vulnerability.
- Verify AntiSSRF efficacy – After deploying AntiSSRF, run the same payload; Dusseldorf should report no callbacks unless the request was to an allowed range.
Advanced: Automate with CI/CD
GitHub Actions step - name: Run Dusseldorf SSRF test run: | ./dusseldorf server & SERVER_PID=$! ./dusseldorf payload --type url --domain localhost:8080 > payload.txt curl -X POST https://myapp.com/test -d "url=$(cat payload.txt)" kill $SERVER_PID Parse logs for callbacks
- Bypass Techniques That AntiSSRF Blocks (And How to Test Them)
Understanding what you’re defending against helps you fine‑tune the runtime agent.
| Bypass Technique | Example URL | How AntiSSRF Blocks |
|-|-|-|
| Decimal IP | `http://2130706433/` (127.0.0.1) | Converts to IP → detects private |
| IPv4‑mapped IPv6 | `http://[::ffff:127.0.0.1]/` | Normalizes to IPv4 → private check |
| DNS Rebinding | Domain resolves to public IP, then switches to 10.0.0.1 | Runtime agent checks each resolved IP at connection time |
| 302 Redirect to internal | `http://attacker.com/redirect` → `http://localhost/admin` | Follows redirect, checks final destination IP |
| URL‑encoding tricks | `http://10.0.0.1%[email protected]/` | Library parses authority correctly before request |
Test each bypass using `curl` after installing AntiSSRF (Node.js example):
const client = createSecureClient();
const bypassAttempts = [
'http://2130706433/',
'http://[::ffff:127.0.0.1]/',
'http://example.com' // DNS rebind simulation requires custom DNS
];
for (const url of bypassAttempts) {
try {
await client.get(url);
console.log(<code>VULNERABLE to ${url}</code>);
} catch (e) {
console.log(<code>Blocked: ${url}</code>);
}
}
6. Cloud Hardening: Protecting AWS/GCP/Azure Metadata
SSRF attacks often target `169.254.169.254` (AWS), `169.254.169.254` (GCP), and `fd00:ec2::254` (Azure IMDS). Even with AntiSSRF, you should layer defenses.
Step‑by‑step cloud hardening with AntiSSRF + IAM policies:
- Block metadata endpoint at network level (e.g., egress firewall rules).
– Linux iptables:
`sudo iptables -A OUTPUT -d 169.254.169.254 -j DROP`
- Windows:
`New-NetFirewallRule -DisplayName “Block Metadata” -Direction Outbound -RemoteAddress 169.254.169.254 -Action Block`
- Configure AntiSSRF to explicitly block cloud metadata IPs (already in default private ranges).
-
Use IMDSv2 on AWS (requires `PUT` token) – this doesn’t prevent SSRF but adds a token requirement.
-
Regularly test with Dusseldorf by injecting metadata‑style URLs:
./dusseldorf payload --type url --domain 169.254.169.254
-
Mitigating SSRF in Legacy Applications (No Library Access)
If you cannot use AntiSSRF (e.g., Python, Ruby, Java legacy apps), implement a sidecar proxy or egress filtering at infrastructure level.
Step‑by‑step egress proxy with Squid (Linux):
1. Install Squid: `sudo apt install squid`
2. Edit `/etc/squid/squid.conf` to deny private IPs:
acl to_private dst 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 127.0.0.0/8 http_access deny to_private
3. Force all outbound HTTP traffic from your app through Squid.
4. For Windows, use `New-NetFirewallRule` with scope to block destinations, or use a reverse proxy like IIS ARR with URL Rewrite rules.
Alternative: DNS‑based blocking (Pi‑hole style)
Add to /etc/hosts on Linux (blocks resolution) echo "0.0.0.0 169.254.169.254" >> /etc/hosts echo ":: 169.254.169.254" >> /etc/hosts
What Undercode Say:
- Key Takeaway 1: Static URL validation is dead. Runtime agents that inspect resolved IPs after DNS are the only reliable defense against SSRF’s endless bypasses.
- Key Takeaway 2: AntiSSRF and Dusseldorf form a complete feedback loop – build with secure defaults, then actively verify with OAST testing.
Analysis: Microsoft’s shift to “secure by default” libraries signals an industry trend: security cannot be an afterthought bolted onto HTTP clients. By embedding runtime checks directly into the request pipeline, they eliminate entire classes of logic bugs that developers introduce (e.g., string concatenation of user input into URLs). The inclusion of Dusseldorf as a complementary testing tool is crucial – many organizations deploy mitigations but never validate they actually work against real rebinding or redirect attacks. Expect to see similar libraries for Python (e.g., a wrapper for requests) and Go soon. For blue teams, now is the time to audit all outbound request code – if you’re still using `WebClient` or `axios` without these guards, you’re likely vulnerable.
Prediction:
Within 12 months, major cloud providers will adopt runtime SSRF agents as default in their SDKs and Lambda runtimes. Attackers will pivot to exploiting SSRF through gopher://, file://, and expect:// protocols that bypass HTTP‑only agents. Microsoft’s team will likely extend AntiSSRF to cover non‑HTTP protocols and implement DNS‑over‑HTTPS checks to prevent rebinding attacks that use short TTLs. Organizations that fail to replace legacy validation logic with runtime agents will suffer breaches via internal port scans and metadata theft.
▶️ Related Video (82% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Clintgibler %F0%9D%90%80%F0%9D%90%A7%F0%9D%90%AD%F0%9D%90%A2%F0%9D%90%92%F0%9D%90%92%F0%9D%90%91%F0%9D%90%85 – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


