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.
4762 vulnerabilities reference this CWE, most recent first.
GHSA-8Q3W-RH8P-P597
Vulnerability from github – Published: 2024-05-14 18:30 – Updated: 2026-04-01 18:31Server-Side Request Forgery (SSRF) vulnerability in ShortPixel ShortPixel Adaptive Images.This issue affects ShortPixel Adaptive Images: from n/a through 3.8.3.
{
"affected": [],
"aliases": [
"CVE-2024-35172"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-05-14T15:39:42Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in ShortPixel ShortPixel Adaptive Images.This issue affects ShortPixel Adaptive Images: from n/a through 3.8.3.",
"id": "GHSA-8q3w-rh8p-p597",
"modified": "2026-04-01T18:31:46Z",
"published": "2024-05-14T18:30:52Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-35172"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/shortpixel-adaptive-images/vulnerability/wordpress-shortpixel-adaptive-images-plugin-3-8-3-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/vulnerability/shortpixel-adaptive-images/wordpress-shortpixel-adaptive-images-plugin-3-8-3-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-8Q49-2H5H-434X
Vulnerability from github – Published: 2026-07-24 22:40 – Updated: 2026-07-24 22:40Summary
The OpenAPI adapter's spec-change poller (OpenApiSpecPoller) re-fetched the
configured spec url on a timer using a raw global fetch(), bypassing the SSRF
guard (safeFetch / assertUrlSafe) that OpenAPIToolGenerator.fromURL() applies
to the initial spec load. As a result, the pinning/DNS-resolution hardening delivered
via mcp-from-openapi >= 2.5.0 (advisory GHSA-65h7-9wrw-629c) protected the initial
load but not the recurring poll of the same URL. When polling is enabled against
an untrusted or attacker-influenceable spec URL, this is an unguarded SSRF vector.
Details
The initial spec load is guarded. OpenapiAdapter resolves a secure refResolution
policy and passes it to the guarded loader:
// libs/adapters/src/openapi/openapi.adapter.ts — initializeGenerator()
return await OpenAPIToolGenerator.fromURL(this.options.url, {
// ...
followRedirects: this.options.loadOptions?.followRedirects ?? false,
refResolution, // secure default: external $refs off, internal targets blocked
});
But the poller — which re-fetches the same URL on every interval — did not:
// libs/adapters/src/openapi/openapi-spec-poller.ts — doFetch() (vulnerable, <= 1.5.5)
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
try {
const response = await fetch(this.url, { // <-- raw global fetch, no SSRF guard
headers,
signal: controller.signal,
});
// ...hash the body, fire onChanged...
}
Because doFetch() never called safeFetch, none of the guard's protections applied
to the polled request:
- no allow-list / block-list enforcement (
allowedHosts/blockedHosts); - no internal/private/loopback/link-local/CGNAT/cloud-metadata IP blocking;
- no DNS resolution of the hostname (so a DNS name that resolves to an internal IP,
e.g.
http://127.0.0.1.nip.io/, was reached); - no connection pinning to the validated IP (DNS-rebinding TOCTOU);
- no per-hop re-validation of HTTP redirects.
This is the identical threat model to fromURL() / external $ref resolution
(GHSA-65h7-9wrw-629c), applied to a request path that the fix for that advisory did
not cover.
Impact
A server that enables spec polling against an untrusted or attacker-influenceable
spec URL will, on every poll interval, issue a server-side GET to whatever host the
URL (or a DNS name it resolves to, or a redirect it returns) points at — including
internal-only addresses unreachable from the public internet. Consequences include:
- reading cloud-instance metadata endpoints (e.g.
169.254.169.254) — credential / token theft; - probing and reaching internal services and private-range hosts (internal network scanning);
- DNS-rebinding to swap a public host for an internal one between validation and connection.
The poller issues GET requests only, so the primary impact is confidentiality
(reaching and reading internal endpoints); the fetched body is content-hashed to
detect change and the subsequent tool rebuild goes back through the guarded
fromURL() path.
Preconditions
Exploitation requires both:
polling.enabled: trueon anOpenapiAdapter(polling is off by default and requires the URL-basedurloption, not an inlinespec); and- the spec
urlis untrusted / attacker-influenceable (e.g. it is derived from user input, a tenant-supplied value, or otherwise not a fixed trusted constant), or an otherwise-trusted spec host is attacker-controlled or can redirect.
Servers that poll a fixed, trusted, first-party spec URL are not exposed in practice, though they still benefit from the guard as defense-in-depth.
Proof of concept
import { OpenapiAdapter } from '@frontmcp/adapters';
// url is attacker-influenceable and points (directly, via DNS, or via redirect)
// at an internal target; polling re-fetches it every interval.
const adapter = OpenapiAdapter.init({
name: 'evil',
url: 'http://169.254.169.254/latest/meta-data/', // or http://127.0.0.1.nip.io/...
polling: { enabled: true, intervalMs: 5000 },
});
await adapter.fetch(); // initial load IS guarded (blocked)
adapter.startPolling(); // <= 1.5.5: each poll issues an UNGUARDED GET to the internal target
On <= 1.5.5 the timed poll reaches the internal address. On the patched version the
poll fails closed (no request is made; the failure is logged) exactly as the initial
load does.
Patch
The fix routes the poller through the same SSRF guard as the initial load, with the same policy, so both paths share one DNS resolution + connection pinning and cannot diverge:
OpenApiSpecPoller.doFetch()now callssafeFetch(this.url, { headers, timeoutMs, followRedirects, ssrf })frommcp-from-openapiinstead of the globalfetch().OpenapiAdapter.startPolling()injects the adapter's resolved policy into the poller:ssrf: normalizeSsrfOptions(this.resolveRefResolution())andfollowRedirects: loadOptions?.followRedirects ?? false— identical to whatfromURL()receives.SpecPollerOptionsgained optionalssrf/followRedirects; standalone use ofOpenApiSpecPollerdefaults to the secure policy (internal targets blocked, redirects not followed).
Files changed:
libs/adapters/src/openapi/openapi-spec-poller.tslibs/adapters/src/openapi/openapi-spec-poller.types.tslibs/adapters/src/openapi/openapi.adapter.ts
Requires mcp-from-openapi >= 2.5.0 (already a dependency at 2.5.1), which exports
safeFetch / normalizeSsrfOptions and performs the resolved-IP validation and
connection pinning.
Remediation
Upgrade @frontmcp/adapters to 1.5.6 or later. No configuration change is required:
polling now inherits the same secure defaults as the initial spec load (external
targets blocked, redirects not followed). To poll a genuinely internal or localhost
spec server in a trusted environment, opt in explicitly with
loadOptions.refResolution.allowInternalIPs: true — the same knob that gates the
initial load.
Workarounds
For users who cannot upgrade immediately:
- disable polling (
polling.enabled: false) on adapters whose specurlis not a fixed, trusted, first-party value; or - only enable polling against spec URLs you fully control, served over HTTPS from a host that cannot be made to redirect to internal targets; and
- enforce network egress controls / an allow-list at the platform layer so the server cannot reach internal ranges or cloud-metadata endpoints.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.5.5"
},
"package": {
"ecosystem": "npm",
"name": "@frontmcp/adapters"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.5.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T22:40:00Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nThe OpenAPI adapter\u0027s spec-change **poller** (`OpenApiSpecPoller`) re-fetched the\nconfigured spec `url` on a timer using a raw global `fetch()`, bypassing the SSRF\nguard (`safeFetch` / `assertUrlSafe`) that `OpenAPIToolGenerator.fromURL()` applies\nto the initial spec load. As a result, the pinning/DNS-resolution hardening delivered\nvia `mcp-from-openapi \u003e= 2.5.0` (advisory GHSA-65h7-9wrw-629c) protected the initial\nload but **not** the recurring poll of the same URL. When polling is enabled against\nan untrusted or attacker-influenceable spec URL, this is an unguarded SSRF vector.\n\n## Details\n\nThe initial spec load is guarded. `OpenapiAdapter` resolves a secure `refResolution`\npolicy and passes it to the guarded loader:\n\n```ts\n// libs/adapters/src/openapi/openapi.adapter.ts \u2014 initializeGenerator()\nreturn await OpenAPIToolGenerator.fromURL(this.options.url, {\n // ...\n followRedirects: this.options.loadOptions?.followRedirects ?? false,\n refResolution, // secure default: external $refs off, internal targets blocked\n});\n```\n\nBut the poller \u2014 which re-fetches **the same URL** on every interval \u2014 did not:\n\n```ts\n// libs/adapters/src/openapi/openapi-spec-poller.ts \u2014 doFetch() (vulnerable, \u003c= 1.5.5)\nconst controller = new AbortController();\nconst timeout = setTimeout(() =\u003e controller.abort(), this.fetchTimeoutMs);\ntry {\n const response = await fetch(this.url, { // \u003c-- raw global fetch, no SSRF guard\n headers,\n signal: controller.signal,\n });\n // ...hash the body, fire onChanged...\n}\n```\n\nBecause `doFetch()` never called `safeFetch`, none of the guard\u0027s protections applied\nto the polled request:\n\n- no allow-list / block-list enforcement (`allowedHosts` / `blockedHosts`);\n- no internal/private/loopback/link-local/CGNAT/cloud-metadata IP blocking;\n- no DNS resolution of the hostname (so a DNS name that resolves to an internal IP,\n e.g. `http://127.0.0.1.nip.io/`, was reached);\n- no connection **pinning** to the validated IP (DNS-rebinding TOCTOU);\n- no per-hop re-validation of HTTP redirects.\n\nThis is the identical threat model to `fromURL()` / external `$ref` resolution\n(GHSA-65h7-9wrw-629c), applied to a request path that the fix for that advisory did\nnot cover.\n\n## Impact\n\nA server that enables spec polling against an untrusted or attacker-influenceable\nspec URL will, on every poll interval, issue a server-side `GET` to whatever host the\nURL (or a DNS name it resolves to, or a redirect it returns) points at \u2014 including\ninternal-only addresses unreachable from the public internet. Consequences include:\n\n- reading cloud-instance metadata endpoints (e.g. `169.254.169.254`) \u2014 credential /\n token theft;\n- probing and reaching internal services and private-range hosts (internal network\n scanning);\n- DNS-rebinding to swap a public host for an internal one between validation and\n connection.\n\nThe poller issues `GET` requests only, so the primary impact is **confidentiality**\n(reaching and reading internal endpoints); the fetched body is content-hashed to\ndetect change and the subsequent tool rebuild goes back through the guarded\n`fromURL()` path.\n\n## Preconditions\n\nExploitation requires **both**:\n\n1. `polling.enabled: true` on an `OpenapiAdapter` (polling is off by default and\n requires the URL-based `url` option, not an inline `spec`); **and**\n2. the spec `url` is untrusted / attacker-influenceable (e.g. it is derived from user\n input, a tenant-supplied value, or otherwise not a fixed trusted constant), or an\n otherwise-trusted spec host is attacker-controlled or can redirect.\n\nServers that poll a fixed, trusted, first-party spec URL are not exposed in practice,\nthough they still benefit from the guard as defense-in-depth.\n\n## Proof of concept\n\n```ts\nimport { OpenapiAdapter } from \u0027@frontmcp/adapters\u0027;\n\n// url is attacker-influenceable and points (directly, via DNS, or via redirect)\n// at an internal target; polling re-fetches it every interval.\nconst adapter = OpenapiAdapter.init({\n name: \u0027evil\u0027,\n url: \u0027http://169.254.169.254/latest/meta-data/\u0027, // or http://127.0.0.1.nip.io/...\n polling: { enabled: true, intervalMs: 5000 },\n});\n\nawait adapter.fetch(); // initial load IS guarded (blocked)\nadapter.startPolling(); // \u003c= 1.5.5: each poll issues an UNGUARDED GET to the internal target\n```\n\nOn `\u003c= 1.5.5` the timed poll reaches the internal address. On the patched version the\npoll fails closed (no request is made; the failure is logged) exactly as the initial\nload does.\n\n## Patch\n\nThe fix routes the poller through the same SSRF guard as the initial load, with the\nsame policy, so both paths share one DNS resolution + connection pinning and cannot\ndiverge:\n\n- `OpenApiSpecPoller.doFetch()` now calls `safeFetch(this.url, { headers, timeoutMs,\n followRedirects, ssrf })` from `mcp-from-openapi` instead of the global `fetch()`.\n- `OpenapiAdapter.startPolling()` injects the adapter\u0027s resolved policy into the\n poller: `ssrf: normalizeSsrfOptions(this.resolveRefResolution())` and\n `followRedirects: loadOptions?.followRedirects ?? false` \u2014 identical to what\n `fromURL()` receives.\n- `SpecPollerOptions` gained optional `ssrf` / `followRedirects`; standalone use of\n `OpenApiSpecPoller` defaults to the secure policy (internal targets blocked,\n redirects not followed).\n\nFiles changed:\n\n- `libs/adapters/src/openapi/openapi-spec-poller.ts`\n- `libs/adapters/src/openapi/openapi-spec-poller.types.ts`\n- `libs/adapters/src/openapi/openapi.adapter.ts`\n\nRequires `mcp-from-openapi \u003e= 2.5.0` (already a dependency at `2.5.1`), which exports\n`safeFetch` / `normalizeSsrfOptions` and performs the resolved-IP validation and\nconnection pinning.\n\n## Remediation\n\nUpgrade `@frontmcp/adapters` to `1.5.6` or later. No configuration change is required:\npolling now inherits the same secure defaults as the initial spec load (external\ntargets blocked, redirects not followed). To poll a genuinely internal or localhost\nspec server in a trusted environment, opt in explicitly with\n`loadOptions.refResolution.allowInternalIPs: true` \u2014 the same knob that gates the\ninitial load.\n\n## Workarounds\n\nFor users who cannot upgrade immediately:\n\n- disable polling (`polling.enabled: false`) on adapters whose spec `url` is not a\n fixed, trusted, first-party value; or\n- only enable polling against spec URLs you fully control, served over HTTPS from a\n host that cannot be made to redirect to internal targets; and\n- enforce network egress controls / an allow-list at the platform layer so the server\n cannot reach internal ranges or cloud-metadata endpoints.",
"id": "GHSA-8q49-2h5h-434x",
"modified": "2026-07-24T22:40:00Z",
"published": "2026-07-24T22:40:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/agentfront/frontmcp/security/advisories/GHSA-8q49-2h5h-434x"
},
{
"type": "WEB",
"url": "https://github.com/agentfront/frontmcp/pull/510"
},
{
"type": "WEB",
"url": "https://github.com/agentfront/frontmcp/commit/077201e109bf6f45dbc85c36d6bd77ded18ab13e"
},
{
"type": "PACKAGE",
"url": "https://github.com/agentfront/frontmcp"
},
{
"type": "WEB",
"url": "https://github.com/agentfront/frontmcp/releases/tag/v1.5.6"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "FrontMCP: Server-Side Request Forgery (SSRF) in the OpenAPI adapter spec-change poller"
}
GHSA-8Q4F-5F8R-VP4W
Vulnerability from github – Published: 2025-12-24 21:30 – Updated: 2025-12-24 21:30Teradek VidiU Pro 3.0.3 contains a server-side request forgery vulnerability in the management interface that allows attackers to manipulate GET parameters 'url' and 'xml_url'. Attackers can exploit this flaw to bypass firewalls, initiate network enumeration, and potentially trigger external HTTP requests to arbitrary destinations.
{
"affected": [],
"aliases": [
"CVE-2019-25251"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-24T20:15:53Z",
"severity": "MODERATE"
},
"details": "Teradek VidiU Pro 3.0.3 contains a server-side request forgery vulnerability in the management interface that allows attackers to manipulate GET parameters \u0027url\u0027 and \u0027xml_url\u0027. Attackers can exploit this flaw to bypass firewalls, initiate network enumeration, and potentially trigger external HTTP requests to arbitrary destinations.",
"id": "GHSA-8q4f-5f8r-vp4w",
"modified": "2025-12-24T21:30:34Z",
"published": "2025-12-24T21:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-25251"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/44672"
},
{
"type": "WEB",
"url": "https://www.teradek.com"
},
{
"type": "WEB",
"url": "https://www.zeroscience.mk/en/vulnerabilities/ZSL-2018-5461.php"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:L/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"
}
]
}
GHSA-8Q6Q-M837-FV64
Vulnerability from github – Published: 2026-07-15 17:31 – Updated: 2026-07-15 17:31Summary
Koel's Subsonic createPodcastChannel.view endpoint accepts a user supplied podcast feed URL and fetches it server-side before applying the safe URL checks that are used for podcast episode enclosure URLs. An authenticated Subsonic API user can provide a loopback or internal URL as the feed URL and cause the Koel backend to issue a request to that address.
A related redirect gap exists in the podcast stream helper: PodcastService::getStreamableUrl() validates only the original URL, then lets Guzzle follow redirects and accepts the final redirected URL without re-validating it.
Impact
An attacker with any valid Koel account and Subsonic API key can trigger server-side requests from the Koel host to loopback or internal network services. This can be used for blind SSRF against internal HTTP endpoints reachable by the Koel deployment. If an internal service returns valid RSS/XML or permissive CORS responses, parts of the response or final URL may be reflected back through normal podcast or stream behavior.
Reproduction
- Start Koel v9.6.0 or current main and create a normal user.
- Obtain the user's Subsonic API key.
- Start a local canary HTTP server on the Koel host at
127.0.0.1:8103that records requests and returns this minimal RSS feed:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Internal Canary Feed</title>
<link>https://example.com/</link>
<description>Internal feed SSRF canary</description>
<item>
<title>Episode One</title>
<guid>koel-internal-canary-episode-1</guid>
<pubDate>Mon, 01 Jun 2026 12:00:00 GMT</pubDate>
<enclosure url="https://example.com/episode.mp3" length="1" type="audio/mpeg" />
</item>
</channel>
</rss>
- Send an authenticated Subsonic request:
GET /rest/createPodcastChannel.view?apiKey=<SUBSONIC_API_KEY>&f=json&url=http://127.0.0.1:8103/feed.xml HTTP/1.1
Host: koel.example
- The endpoint returns a successful Subsonic response and the canary records a backend request:
GET /feed.xml
Unauthenticated control: the same request without a valid API key fails and does not hit the canary.
Redirect control for the stream helper: calling PodcastService::getStreamableUrl() with direct http://127.0.0.1:8102/secret returns null and makes no canary request. Calling it with a safe-looking public URL that redirects to http://127.0.0.1:8102/secret causes the backend to request OPTIONS /secret and returns the loopback final URL.
Root cause
app/Http/Requests/Subsonic/CreatePodcastChannelRequest.php validates url only as required|string|url. The controller passes it to PodcastService::addPodcast(), where PodcastService.php calls createParser($url) and Poddle::fromUrl($url, ...) before any Network::isSafeUrl() check. The enclosure URL guard in synchronizeEpisodes() runs later and only covers episode enclosure URLs, not the feed URL that was already fetched.
For streaming, PodcastService::getStreamableUrl() checks Network::isSafeUrl($url) on the original URL, then follows redirects with Guzzle and accepts the last redirect target from X-Guzzle-Redirect-History without validating that target.
Remediation
Validate the podcast feed URL with the same safe URL policy before Poddle::fromUrl() performs any request. Re-validate every redirect target before following it, or disable automatic redirects and manually fetch only targets that pass the safe URL policy. Apply the same redirect validation in getStreamableUrl(). Add regression tests for direct loopback and private IP feed URLs, DNS names resolving to private ranges, and public URL to loopback redirects.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.6.0"
},
"package": {
"ecosystem": "Packagist",
"name": "phanan/koel"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "9.7.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-15T17:31:12Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nKoel\u0027s Subsonic `createPodcastChannel.view` endpoint accepts a user supplied podcast feed URL and fetches it server-side before applying the safe URL checks that are used for podcast episode enclosure URLs. An authenticated Subsonic API user can provide a loopback or internal URL as the feed URL and cause the Koel backend to issue a request to that address.\n\nA related redirect gap exists in the podcast stream helper: `PodcastService::getStreamableUrl()` validates only the original URL, then lets Guzzle follow redirects and accepts the final redirected URL without re-validating it.\n\n## Impact\n\nAn attacker with any valid Koel account and Subsonic API key can trigger server-side requests from the Koel host to loopback or internal network services. This can be used for blind SSRF against internal HTTP endpoints reachable by the Koel deployment. If an internal service returns valid RSS/XML or permissive CORS responses, parts of the response or final URL may be reflected back through normal podcast or stream behavior.\n\n## Reproduction\n\n1. Start Koel v9.6.0 or current main and create a normal user.\n2. Obtain the user\u0027s Subsonic API key.\n3. Start a local canary HTTP server on the Koel host at `127.0.0.1:8103` that records requests and returns this minimal RSS feed:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003crss version=\"2.0\"\u003e\n \u003cchannel\u003e\n \u003ctitle\u003eInternal Canary Feed\u003c/title\u003e\n \u003clink\u003ehttps://example.com/\u003c/link\u003e\n \u003cdescription\u003eInternal feed SSRF canary\u003c/description\u003e\n \u003citem\u003e\n \u003ctitle\u003eEpisode One\u003c/title\u003e\n \u003cguid\u003ekoel-internal-canary-episode-1\u003c/guid\u003e\n \u003cpubDate\u003eMon, 01 Jun 2026 12:00:00 GMT\u003c/pubDate\u003e\n \u003cenclosure url=\"https://example.com/episode.mp3\" length=\"1\" type=\"audio/mpeg\" /\u003e\n \u003c/item\u003e\n \u003c/channel\u003e\n\u003c/rss\u003e\n```\n\n4. Send an authenticated Subsonic request:\n\n```http\nGET /rest/createPodcastChannel.view?apiKey=\u003cSUBSONIC_API_KEY\u003e\u0026f=json\u0026url=http://127.0.0.1:8103/feed.xml HTTP/1.1\nHost: koel.example\n```\n\n5. The endpoint returns a successful Subsonic response and the canary records a backend request:\n\n```text\nGET /feed.xml\n```\n\nUnauthenticated control: the same request without a valid API key fails and does not hit the canary.\n\nRedirect control for the stream helper: calling `PodcastService::getStreamableUrl()` with direct `http://127.0.0.1:8102/secret` returns `null` and makes no canary request. Calling it with a safe-looking public URL that redirects to `http://127.0.0.1:8102/secret` causes the backend to request `OPTIONS /secret` and returns the loopback final URL.\n\n## Root cause\n\n`app/Http/Requests/Subsonic/CreatePodcastChannelRequest.php` validates `url` only as `required|string|url`. The controller passes it to `PodcastService::addPodcast()`, where `PodcastService.php` calls `createParser($url)` and `Poddle::fromUrl($url, ...)` before any `Network::isSafeUrl()` check. The enclosure URL guard in `synchronizeEpisodes()` runs later and only covers episode enclosure URLs, not the feed URL that was already fetched.\n\nFor streaming, `PodcastService::getStreamableUrl()` checks `Network::isSafeUrl($url)` on the original URL, then follows redirects with Guzzle and accepts the last redirect target from `X-Guzzle-Redirect-History` without validating that target.\n\n## Remediation\n\nValidate the podcast feed URL with the same safe URL policy before `Poddle::fromUrl()` performs any request. Re-validate every redirect target before following it, or disable automatic redirects and manually fetch only targets that pass the safe URL policy. Apply the same redirect validation in `getStreamableUrl()`. Add regression tests for direct loopback and private IP feed URLs, DNS names resolving to private ranges, and public URL to loopback redirects.",
"id": "GHSA-8q6q-m837-fv64",
"modified": "2026-07-15T17:31:12Z",
"published": "2026-07-15T17:31:12Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/koel/koel/security/advisories/GHSA-8q6q-m837-fv64"
},
{
"type": "PACKAGE",
"url": "https://github.com/koel/koel"
},
{
"type": "WEB",
"url": "https://github.com/koel/koel/releases/tag/v9.7.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": " Koel has SSRF through Authenticated Subsonic podcast feed URLs"
}
GHSA-8Q72-V33X-GGGR
Vulnerability from github – Published: 2024-06-07 06:30 – Updated: 2026-04-08 18:33The TablePress – Tables in WordPress made easy plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 2.3 via the get_files_to_import() function. This makes it possible for authenticated attackers, with author-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services. Due to the complex nature of protecting against DNS rebind attacks in WordPress software, we settled on the developer simply restricting the usage of the URL import functionality to just administrators. While this is not optimal, we feel this poses a minimal risk to most site owners and ideally WordPress core would correct this issue in wp_safe_remote_get() and other functions.
{
"affected": [],
"aliases": [
"CVE-2024-4354"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-06-07T06:15:11Z",
"severity": "MODERATE"
},
"details": "The TablePress \u2013 Tables in WordPress made easy plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 2.3 via the get_files_to_import() function. This makes it possible for authenticated attackers, with author-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services. Due to the complex nature of protecting against DNS rebind attacks in WordPress software, we settled on the developer simply restricting the usage of the URL import functionality to just administrators. While this is not optimal, we feel this poses a minimal risk to most site owners and ideally WordPress core would correct this issue in wp_safe_remote_get() and other functions.",
"id": "GHSA-8q72-v33x-gggr",
"modified": "2026-04-08T18:33:21Z",
"published": "2024-06-07T06:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-4354"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/tablepress/trunk/classes/class-import.php#L125"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/tablepress/trunk/classes/class-import.php#L141"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026old=3097113%40tablepress\u0026new=3097113%40tablepress\u0026sfp_email=\u0026sfph_mail="
},
{
"type": "WEB",
"url": "https://www.clear-gate.com/blog/ssrf-with-dns-rebinding-2"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/879384eb-bfea-4667-a7de-9f723dbea74b?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-8Q87-6J7G-5QCF
Vulnerability from github – Published: 2022-05-24 17:40 – Updated: 2022-05-24 17:40IBM QRadar SIEM 7.4.2 GA to 7.4.2 Patch 1, 7.4.0 to 7.4.1 Patch 1, and 7.3.0 to 7.3.3 Patch 5 is vulnerable to server side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks. IBM X-Force ID: 189224.
{
"affected": [],
"aliases": [
"CVE-2020-4787"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-01-27T17:15:00Z",
"severity": "LOW"
},
"details": "IBM QRadar SIEM 7.4.2 GA to 7.4.2 Patch 1, 7.4.0 to 7.4.1 Patch 1, and 7.3.0 to 7.3.3 Patch 5 is vulnerable to server side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks. IBM X-Force ID: 189224.",
"id": "GHSA-8q87-6j7g-5qcf",
"modified": "2022-05-24T17:40:26Z",
"published": "2022-05-24T17:40:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-4787"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/189224"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/6408864"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-8QG6-GQ98-W657
Vulnerability from github – Published: 2026-05-11 21:31 – Updated: 2026-05-11 21:31A security vulnerability has been detected in jishenghua jshERP up to 3.6. This affects the function getUserByWeixinCode of the file jshERP-boot/src/main/java/com/jsh/erp/service/UserService.java of the component updatePlatformConfigByKey Endpoint. Such manipulation of the argument weixinUrl leads to server-side request forgery. The attack can be executed remotely. The exploit has been disclosed publicly and may be used. The project was informed of the problem early through an issue report but has not responded yet.
{
"affected": [],
"aliases": [
"CVE-2026-8320"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-11T20:25:48Z",
"severity": "LOW"
},
"details": "A security vulnerability has been detected in jishenghua jshERP up to 3.6. This affects the function getUserByWeixinCode of the file jshERP-boot/src/main/java/com/jsh/erp/service/UserService.java of the component updatePlatformConfigByKey Endpoint. Such manipulation of the argument weixinUrl leads to server-side request forgery. The attack can be executed remotely. The exploit has been disclosed publicly and may be used. The project was informed of the problem early through an issue report but has not responded yet.",
"id": "GHSA-8qg6-gq98-w657",
"modified": "2026-05-11T21:31:37Z",
"published": "2026-05-11T21:31:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-8320"
},
{
"type": "WEB",
"url": "https://github.com/jishenghua/jshERP/issues/152"
},
{
"type": "WEB",
"url": "https://github.com/jishenghua/jshERP"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/811303"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/362607"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/362607/cti"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P/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"
}
]
}
GHSA-8QP7-PRCQ-V2M5
Vulnerability from github – Published: 2023-01-26 21:30 – Updated: 2023-02-06 21:30A Server Side Request Forgery (SSRF) vulnerability exists in Tenable.sc due to improper validation of session & user-accessible input data. A privileged, authenticated remote attacker could interact with external and internal services covertly.
{
"affected": [],
"aliases": [
"CVE-2023-24495"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-01-26T21:18:00Z",
"severity": "MODERATE"
},
"details": "A Server Side Request Forgery (SSRF) vulnerability exists in Tenable.sc due to improper validation of session \u0026 user-accessible input data. A privileged, authenticated remote attacker could interact with external and internal services covertly.",
"id": "GHSA-8qp7-prcq-v2m5",
"modified": "2023-02-06T21:30:34Z",
"published": "2023-01-26T21:30:17Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-24495"
},
{
"type": "WEB",
"url": "https://www.tenable.com/security/tns-2023-03"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-8QPJ-GGQR-96FP
Vulnerability from github – Published: 2025-03-26 12:30 – Updated: 2025-03-26 12:30The Zapier for WordPress plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.5.1 via the updated_user() function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application which can be used to query and modify information from internal services.
{
"affected": [],
"aliases": [
"CVE-2024-13411"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-03-26T12:15:13Z",
"severity": "MODERATE"
},
"details": "The Zapier for WordPress plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.5.1 via the updated_user() function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application which can be used to query and modify information from internal services.",
"id": "GHSA-8qpj-ggqr-96fp",
"modified": "2025-03-26T12:30:34Z",
"published": "2025-03-26T12:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-13411"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/zapier/trunk/zapier.php#L114"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/zapier/trunk/zapier.php#L210"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/zapier/trunk/zapier.php#L284"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3257975"
},
{
"type": "WEB",
"url": "https://wordpress.org/plugins/zapier/#developers"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/701dc461-88e7-40bf-a4fb-f92723b6e05e?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-8QQF-JX6G-2RCV
Vulnerability from github – Published: 2022-05-15 00:00 – Updated: 2022-05-25 00:00URL Restriction Bypass in GitHub repository plantuml/plantuml prior to V1.2022.5. An attacker can abuse this to bypass URL restrictions that are imposed by the different security profiles and achieve server side request forgery (SSRF). This allows accessing restricted internal resources/servers or sending requests to third party servers.
{
"affected": [],
"aliases": [
"CVE-2022-1379"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-05-14T10:15:00Z",
"severity": "CRITICAL"
},
"details": "URL Restriction Bypass in GitHub repository plantuml/plantuml prior to V1.2022.5. An attacker can abuse this to bypass URL restrictions that are imposed by the different security profiles and achieve server side request forgery (SSRF). This allows accessing restricted internal resources/servers or sending requests to third party servers.",
"id": "GHSA-8qqf-jx6g-2rcv",
"modified": "2022-05-25T00:00:32Z",
"published": "2022-05-15T00:00:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-1379"
},
{
"type": "WEB",
"url": "https://github.com/plantuml/plantuml/commit/93e5964e5f35914f3f7b89de620c596795550083"
},
{
"type": "WEB",
"url": "https://huntr.dev/bounties/0d737527-86e1-41d1-9d37-b2de36bc063a"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/CHUE4G5CAJUD7L2QPJF6U4JYQTP7CNNL"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/J4DP36G2VBOZUNQIUZ5LVJKZIVO4SDAI"
}
],
"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"
}
]
}
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.