Common Weakness Enumeration

CWE-918

Allowed

Server-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.

4719 vulnerabilities reference this CWE, most recent first.

GHSA-6Q25-74P4-X9QC

Vulnerability from github – Published: 2022-05-24 19:05 – Updated: 2022-05-24 19:05
VLAI
Details

IBM Security Identity Manager 6.0.2 is vulnerable to server-side request forgery (SSRF). By sending a specially crafted request, a remote authenticated attacker could exploit this vulnerability to obtain sensitive data. IBM X-Force ID: 197591.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-20483"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-06-16T17:15:00Z",
    "severity": "MODERATE"
  },
  "details": "IBM Security Identity Manager 6.0.2 is vulnerable to server-side request forgery (SSRF). By sending a specially crafted request, a remote authenticated attacker could exploit this vulnerability to obtain sensitive data. IBM X-Force ID: 197591.",
  "id": "GHSA-6q25-74p4-x9qc",
  "modified": "2022-05-24T19:05:29Z",
  "published": "2022-05-24T19:05:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-20483"
    },
    {
      "type": "WEB",
      "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/197591"
    },
    {
      "type": "WEB",
      "url": "https://www.ibm.com/support/pages/node/6464081"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-6Q3P-36F4-CWXV

Vulnerability from github – Published: 2021-09-20 20:45 – Updated: 2021-09-16 18:52
VLAI
Summary
Server-Side Request Forgery in UReport
Details

UReport v2.2.9 contains a Server-Side Request Forgery (SSRF) in the designer page which allows attackers to detect intranet device ports.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.bstek.ureport:ureport2-console"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "2.2.9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2020-21122"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2021-09-16T18:52:16Z",
    "nvd_published_at": "2021-09-15T17:15:00Z",
    "severity": "HIGH"
  },
  "details": "UReport v2.2.9 contains a Server-Side Request Forgery (SSRF) in the designer page which allows attackers to detect intranet device ports.",
  "id": "GHSA-6q3p-36f4-cwxv",
  "modified": "2021-09-16T18:52:16Z",
  "published": "2021-09-20T20:45:21Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-21122"
    },
    {
      "type": "WEB",
      "url": "https://github.com/youseries/ureport/issues/483"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/youseries/ureport"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [],
  "summary": "Server-Side Request Forgery in UReport"
}

GHSA-6Q52-MR9G-RHRV

Vulnerability from github – Published: 2022-05-24 19:08 – Updated: 2024-03-19 18:31
VLAI
Details

IBM Secure External Authentication Server 6.0.2 and IBM Secure Proxy 6.0.2 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: 201777.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-29749"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-07-15T16:15:00Z",
    "severity": "MODERATE"
  },
  "details": "IBM Secure External Authentication Server 6.0.2 and IBM Secure Proxy 6.0.2 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: 201777.",
  "id": "GHSA-6q52-mr9g-rhrv",
  "modified": "2024-03-19T18:31:58Z",
  "published": "2022-05-24T19:08:11Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-29749"
    },
    {
      "type": "WEB",
      "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/201777"
    },
    {
      "type": "WEB",
      "url": "https://www.ibm.com/support/pages/node/6471621"
    },
    {
      "type": "WEB",
      "url": "https://www.ibm.com/support/pages/node/6471623"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-6Q93-RCG3-J5M7

Vulnerability from github – Published: 2025-04-01 15:31 – Updated: 2026-04-01 18:34
VLAI
Details

Server-Side Request Forgery (SSRF) vulnerability in TheInnovs Team ElementsCSS Addons for Elementor allows Server Side Request Forgery. This issue affects ElementsCSS Addons for Elementor: from n/a through 1.0.8.7.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-31796"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-04-01T15:16:17Z",
    "severity": "MODERATE"
  },
  "details": "Server-Side Request Forgery (SSRF) vulnerability in TheInnovs Team ElementsCSS Addons for Elementor allows Server Side Request Forgery. This issue affects ElementsCSS Addons for Elementor: from n/a through 1.0.8.7.",
  "id": "GHSA-6q93-rcg3-j5m7",
  "modified": "2026-04-01T18:34:20Z",
  "published": "2025-04-01T15:31:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-31796"
    },
    {
      "type": "WEB",
      "url": "https://patchstack.com/database/wordpress/plugin/css-for-elementor/vulnerability/wordpress-elementscss-addons-for-elementor-plugin-1-0-8-7-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-6Q96-CQF2-7RW3

Vulnerability from github – Published: 2025-03-31 15:30 – Updated: 2025-03-31 15:30
VLAI
Details

A vulnerability was found in zhangyanbo2007 youkefu 4.2.0. It has been classified as critical. Affected is an unknown function of the file /res/url. The manipulation of the argument url leads to server-side request forgery. It is possible to launch the attack remotely. The exploit has been disclosed to the public and may be used.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-2997"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-03-31T14:15:20Z",
    "severity": "MODERATE"
  },
  "details": "A vulnerability was found in zhangyanbo2007 youkefu 4.2.0. It has been classified as critical. Affected is an unknown function of the file /res/url. The manipulation of the argument url leads to server-side request forgery. It is possible to launch the attack remotely. The exploit has been disclosed to the public and may be used.",
  "id": "GHSA-6q96-cqf2-7rw3",
  "modified": "2025-03-31T15:30:48Z",
  "published": "2025-03-31T15:30:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-2997"
    },
    {
      "type": "WEB",
      "url": "https://github.com/exp3n5ive/Vul/blob/main/youkefu/youkefu.pdf"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?ctiid.302046"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?id.302046"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?submit.524009"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/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"
    }
  ]
}

GHSA-6QCR-QXGR-M7FV

Vulnerability from github – Published: 2026-07-07 13:01 – Updated: 2026-07-07 13:01
VLAI
Summary
New API: SSRF Protection Bypass via Unresolved Hostname in Notification URLs
Details

Summary

The default SSRF protection configuration did not apply IP filtering to hostnames. With ApplyIPFilterForDomain disabled by default, URL validation checked domain allow/block rules but did not resolve a hostname and validate the resolved IP address. Authenticated users could configure notification URLs for Webhook, Bark, or Gotify notifications and point a hostname at an internal or metadata IP address.

Impact

A regular authenticated user could cause the server to send notification requests to internal HTTP services reachable from the deployment network. Depending on the target environment, this could expose sensitive internal data through timing, errors, or response-dependent behavior. The issue is rated High.

Affected versions

Versions before v0.12.0-alpha.1 are affected. The previous affected range of <= v0.11.4-alpha.4 was too narrow because the unsafe default remained present until the v0.12.0-alpha.1 fix.

Patches

This issue is fixed in v0.12.0-alpha.1. The default fetch setting now sets ApplyIPFilterForDomain: true, causing hostname destinations to be resolved and checked against the configured IP filtering rules during URL validation.

This patch addresses the unresolved-hostname bypass for the affected notification URL paths. It does not mark the separate DNS rebinding advisory as fixed, because connection-time IP enforcement is tracked separately.

Workarounds

If upgrading immediately is not possible, explicitly enable ApplyIPFilterForDomain, restrict notification URL domains with an allowlist, disable user-configurable notification URLs where practical, and enforce outbound network filtering at the host or network layer.

Resources

  • Fixed by commit 20399d3c8fcb4e3649d53163eb11940fd6763743.
  • Relevant code paths: setting/system_setting/fetch_setting.go, common/ssrf_protection.go, service/webhook.go, and service/user_notify.go.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/QuantumNous/new-api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.12.0-alpha.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-33655"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-07T13:01:12Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\nThe default SSRF protection configuration did not apply IP filtering to hostnames. With `ApplyIPFilterForDomain` disabled by default, URL validation checked domain allow/block rules but did not resolve a hostname and validate the resolved IP address. Authenticated users could configure notification URLs for Webhook, Bark, or Gotify notifications and point a hostname at an internal or metadata IP address.\n\n## Impact\n\nA regular authenticated user could cause the server to send notification requests to internal HTTP services reachable from the deployment network. Depending on the target environment, this could expose sensitive internal data through timing, errors, or response-dependent behavior. The issue is rated High.\n\n## Affected versions\n\nVersions before `v0.12.0-alpha.1` are affected. The previous affected range of `\u003c= v0.11.4-alpha.4` was too narrow because the unsafe default remained present until the `v0.12.0-alpha.1` fix.\n\n## Patches\n\nThis issue is fixed in `v0.12.0-alpha.1`. The default fetch setting now sets `ApplyIPFilterForDomain: true`, causing hostname destinations to be resolved and checked against the configured IP filtering rules during URL validation.\n\nThis patch addresses the unresolved-hostname bypass for the affected notification URL paths. It does not mark the separate DNS rebinding advisory as fixed, because connection-time IP enforcement is tracked separately.\n\n## Workarounds\n\nIf upgrading immediately is not possible, explicitly enable `ApplyIPFilterForDomain`, restrict notification URL domains with an allowlist, disable user-configurable notification URLs where practical, and enforce outbound network filtering at the host or network layer.\n\n## Resources\n\n- Fixed by commit `20399d3c8fcb4e3649d53163eb11940fd6763743`.\n- Relevant code paths: `setting/system_setting/fetch_setting.go`, `common/ssrf_protection.go`, `service/webhook.go`, and `service/user_notify.go`.",
  "id": "GHSA-6qcr-qxgr-m7fv",
  "modified": "2026-07-07T13:01:12Z",
  "published": "2026-07-07T13:01:12Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/QuantumNous/new-api/security/advisories/GHSA-6qcr-qxgr-m7fv"
    },
    {
      "type": "WEB",
      "url": "https://github.com/QuantumNous/new-api/commit/20399d3c8fcb4e3649d53163eb11940fd6763743"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/QuantumNous/new-api"
    }
  ],
  "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": "New API: SSRF Protection Bypass via Unresolved Hostname in Notification URLs"
}

GHSA-6QHC-X826-342C

Vulnerability from github – Published: 2026-06-16 21:02 – Updated: 2026-07-20 21:12
VLAI
Summary
Crawl4AI: SSRF via proxy settings in the Docker server bypasses the crawl-URL SSRF check
Details

Summary

The Docker API server applied its SSRF destination check to the crawl target URL only, not to the proxy address. An unauthenticated request could supply a proxy pointing at an internal IP and route the browser through it, reaching internal services and cloud-metadata endpoints, while using a perfectly valid crawl URL. The Docker API is unauthenticated by default.

Affected paths

/crawl, /crawl/stream, and /crawl/job accept a browser_config (and crawler_config). The following all feed Chromium's egress and were unchecked: - browser_config.proxy_config.server - browser_config.proxy (deprecated field) - crawler_config.proxy_config.server - --proxy-server / --proxy-pac-url / --proxy-bypass-list / --host-resolver-rules flags in browser_config.extra_args

Attack

An attacker sends /crawl with a benign, validation-passing URL but a proxy_config.server pointing at an internal IP. Chromium routes all requests through that proxy. For plain-HTTP targets the proxy receives the full request and can return any content, which is then returned verbatim in the crawl result (results[0].html / cleaned_html / markdown). In a real deployment the proxy would be an attacker-controlled server pointing at cloud metadata (e.g. AWS IMDSv1 at 169.254.169.254) to retrieve IAM credential tokens.

Impact

Unauthenticated server-side request forgery to internal services and cloud-metadata endpoints, with the response returned to the attacker.

Fix

Every proxy destination is validated with the same global-routability check used for crawl URLs (reject any resolved address that is not is_global, including IPv6 transition forms) before the browser is constructed; proxy/DNS-redirecting flags are stripped from extra_args. A legitimate public proxy still works. Honors CRAWL4AI_ALLOW_INTERNAL_URLS.

Workarounds

  • Upgrade to the patched version (0.8.9).
  • Enable authentication (CRAWL4AI_API_TOKEN).
  • Restrict the container's outbound network access (egress firewall / no metadata route).

Credits

Geo (geo-chen) - reported the proxy_config.server SSRF with a clear PoC.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.8.8"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "crawl4ai"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.8.9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-53755"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-16T21:02:55Z",
    "nvd_published_at": "2026-06-23T19:17:07Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nThe Docker API server applied its SSRF destination check to the crawl target URL only, not to the proxy address. An unauthenticated request could supply a proxy pointing at an internal IP and route the browser through it, reaching internal services and cloud-metadata endpoints, while using a perfectly valid crawl URL. The Docker API is unauthenticated by default.\n\n### Affected paths\n\n`/crawl`, `/crawl/stream`, and `/crawl/job` accept a `browser_config` (and `crawler_config`). The following all feed Chromium\u0027s egress and were unchecked:\n- `browser_config.proxy_config.server`\n- `browser_config.proxy` (deprecated field)\n- `crawler_config.proxy_config.server`\n- `--proxy-server` / `--proxy-pac-url` / `--proxy-bypass-list` / `--host-resolver-rules` flags in `browser_config.extra_args`\n\n### Attack\n\nAn attacker sends `/crawl` with a benign, validation-passing URL but a `proxy_config.server` pointing at an internal IP. Chromium routes all requests through that proxy. For plain-HTTP targets the proxy receives the full request and can return any content, which is then returned verbatim in the crawl result (`results[0].html` / `cleaned_html` / `markdown`). In a real deployment the proxy would be an attacker-controlled server pointing at cloud metadata (e.g. AWS IMDSv1 at 169.254.169.254) to retrieve IAM credential tokens.\n\n### Impact\n\nUnauthenticated server-side request forgery to internal services and cloud-metadata endpoints, with the response returned to the attacker.\n\n### Fix\n\nEvery proxy destination is validated with the same global-routability check used for crawl URLs (reject any resolved address that is not `is_global`, including IPv6 transition forms) before the browser is constructed; proxy/DNS-redirecting flags are stripped from `extra_args`. A legitimate public proxy still works. Honors `CRAWL4AI_ALLOW_INTERNAL_URLS`.\n\n### Workarounds\n\n- Upgrade to the patched version (0.8.9).\n- Enable authentication (`CRAWL4AI_API_TOKEN`).\n- Restrict the container\u0027s outbound network access (egress firewall / no metadata route).\n\n### Credits\n\nGeo ([geo-chen](https://github.com/geo-chen)) - reported the proxy_config.server SSRF with a clear PoC.",
  "id": "GHSA-6qhc-x826-342c",
  "modified": "2026-07-20T21:12:12Z",
  "published": "2026-06-16T21:02:55Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/unclecode/crawl4ai/security/advisories/GHSA-6qhc-x826-342c"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-53755"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/crawl4ai/PYSEC-2026-588.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/unclecode/crawl4ai"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Crawl4AI: SSRF via proxy settings in the Docker server bypasses the crawl-URL SSRF check"
}

GHSA-6QHV-QCCP-876Q

Vulnerability from github – Published: 2026-03-25 18:31 – Updated: 2026-03-25 21:30
VLAI
Details

Server-Side Request Forgery (SSRF) vulnerability in Drupal Drupal Canvas allows Server Side Request Forgery.This issue affects Drupal Canvas: from 0.0.0 before 1.1.1.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-3216"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-03-25T16:16:22Z",
    "severity": "MODERATE"
  },
  "details": "Server-Side Request Forgery (SSRF) vulnerability in Drupal Drupal Canvas allows Server Side Request Forgery.This issue affects Drupal Canvas: from 0.0.0 before 1.1.1.",
  "id": "GHSA-6qhv-qccp-876q",
  "modified": "2026-03-25T21:30:33Z",
  "published": "2026-03-25T18:31:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3216"
    },
    {
      "type": "WEB",
      "url": "https://www.drupal.org/sa-contrib-2026-017"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-6QJW-GMVP-Q3JV

Vulnerability from github – Published: 2026-05-09 21:32 – Updated: 2026-05-09 21:32
VLAI
Details

A weakness has been identified in Akaunting 3.1.21. This issue affects some unknown processing of the file config/dompdf.php of the component Invoice PDF Rendering. Executing a manipulation can lead to server-side request forgery. The attack may be launched remotely. The exploit has been made available to the public and could be used for attacks. The vendor was contacted early about this disclosure but did not respond in any way.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-8193"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-09T19:16:10Z",
    "severity": "LOW"
  },
  "details": "A weakness has been identified in Akaunting 3.1.21. This issue affects some unknown processing of the file config/dompdf.php of the component Invoice PDF Rendering. Executing a manipulation can lead to server-side request forgery. The attack may be launched remotely. The exploit has been made available to the public and could be used for attacks. The vendor was contacted early about this disclosure but did not respond in any way.",
  "id": "GHSA-6qjw-gmvp-q3jv",
  "modified": "2026-05-09T21:32:41Z",
  "published": "2026-05-09T21:32:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-8193"
    },
    {
      "type": "WEB",
      "url": "https://drive.google.com/file/d/1zC8gMYeIfZi3CsK6RXBQINU_mllXH_6n/view?usp=drive_link"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/submit/800984"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/362345"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/362345/cti"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/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-6QVR-WJMV-V8MM

Vulnerability from github – Published: 2026-07-15 17:59 – Updated: 2026-07-15 17:59
VLAI
Summary
Koel: Incomplete fix for CVE-2026-47260 — systemic SSRF in podcast & radio fetch paths
Details

Summary

The fix for CVE-2026-47260 (v9.3.5) added an initial isSafeUrl() check to several fetchers (synchronizeEpisodes, getStreamableUrl, AddRadioStation, EpisodePlayable), but the redirect-target validation — the per-hop Guzzle on_redirect callback added in follow-up commit be1e867 — was applied to only one path, EpisodePlayable. Every other server-side fetcher therefore has only the initial check, which an HTTP 302 redirect to an internal address bypasses, or no check at all. DNS rebinding (validation and connection resolve DNS separately, with no IP pinning) bypasses the initial check on every path.

An authenticated, non-admin user can thus cause the Koel server to issue requests to arbitrary internal / cloud-metadata endpoints (SSRF) by supplying a URL on an attacker-controlled host that 302-redirects to an internal address.

Note: commit be1e867 shows the redirect-based SSRF vector was recognised, but the redirect defense was applied to a single call site rather than generalised — so the class survives in the sibling paths below.

Details — Root cause

App\Helpers\Network::isPublicHost() / isSafeUrl() perform a point-in-time host check with no pinning of the resolved IP, and per-redirect-hop re-validation exists only in App\Values\Podcast\EpisodePlayable (the on_redirect callback from commit be1e867). Consequently every other fetcher is exposed to (1) redirect SSRF — initial URL passes isSafeUrl, then the HTTP client follows a cross-host 302 to an internal target without re-validating the hop; and (2) DNS rebinding (TOCTOU)isPublicHost resolves DNS at validation, the HTTP client resolves again at connect time.

Affected paths (all reachable by any authenticated user)

# Location Issue
1 PhanAn\Poddle\Poddle::fromUrl()Http::timeout()->get($url) (used by PodcastService::addPodcast/refreshPodcast) Plain Http::get, follows redirects, no per-hop validation; refreshPodcast does not re-run isSafeUrl at all
2 PodcastService::getStreamableUrl() (PodcastService.php:244/251) Has the initial isSafeUrl() (line 244) but the request uses ALLOW_REDIRECTS => ['track_redirects' => true] with no on_redirect → 302 to internal is followed. Called at episode stream time via PodcastStreamerAdapter. Also DNS-rebinding-exposed
3 PodcastService::isPodcastObsolete() (:221) Http::head($podcast->url) No isSafeUrl, no redirect validation
4 App\Rules\HasAudioContentType (:45/:54) Http::head/Http::get Self-documented "use after SafeUrl"; ordering-dependent, no own validation, no per-hop check. Extends the surface to the internet-radio feature (RadioStationStore/UpdateRequest)
5 App\Rules\SafeUrl validator (:52/:56) Follows redirects, validates only the final effective host — intermediate-hop requests still fire

Reachable via the native API (apiResource podcasts, radio/stations; PodcastController::store has no authorization check, only #[DisabledInDemo]) and the Subsonic API (createPodcastChannel, createInternetRadioStation, refreshPodcasts).

PoC

A mechanism PoC that runs the exact Guzzle/Laravel-Http call shapes Koel uses (attacker-redirect server + internal-target listener on loopback), verified on PHP 8.2 + Guzzle 7:

isPublicHost('127.0.0.1') = false        # a per-hop check WOULD block this
Case1 Poddle::fromUrl        -> [VULNERABLE]  leaked INTERNAL-SECRET-TOKEN
Case2 getStreamableUrl       -> [VULNERABLE]  leaked INTERNAL-SECRET-TOKEN
Case3 EpisodePlayable        -> [BLOCKED]     UnsafeUrl on redirect
internal_hits.log: 2 hits    # internal service actually reached by Case1 + Case2

Case1/Case2 reaching the internal target while Case3 (the fixed path) blocks under identical conditions demonstrates the incomplete remediation. The full PoC kit (poc.php, attacker_router.php, internal_router.php) is available on request.

End-to-end on a real instance: an authenticated user POST /api/podcasts (or Subsonic createPodcastChannel) with a feed URL on an attacker host that returns 302 Location: http://169.254.169.254/latest/meta-data/... (or http://127.0.0.1:<port>/); the server follows it. The response is reflected back via parsed podcast fields / getStreamableUrl when the internal endpoint returns Access-Control-Allow-Origin: *; otherwise blind SSRF via status/timing.

Impact

Authenticated (any user) SSRF: access to cloud instance metadata (IAM credentials on IMDSv1), internal-only admin panels, and internal network service probing — from the Koel server's network position. Same threat model as CVE-2026-47260.

Attack scenario (fully remote, no user interaction): the only precondition is a single low-privilege account. On AWS/GCP/Azure-hosted instances, redirecting to the metadata IP and reflecting the body discloses temporary IAM credentials → cloud-account pivot. (AWS IMDSv2's token-via-PUT is not reachable through a simple GET-redirect SSRF; IMDSv1 instances are fully exposed.) "Koel only runs on an internal/trusted network" does not reduce the risk — the bug makes the Koel server itself the attacker's pivot into that trusted network and cloud control plane.

Suggested severity: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N (7.1); lower where exploitation is blind.

Remediation

Do not fix per-call-site. Centralize: route all outbound HTTP through a shared Guzzle handler/middleware that, on every connection and every redirect hop, resolves the target and rejects private/reserved IPs, and pins the validated IP for the actual connection (defeats DNS rebinding). Apply to EpisodePlayable, getStreamableUrl, Poddle::fromUrl usage, isPodcastObsolete, HasAudioContentType, and the SafeUrl rule.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 9.7.0"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "phanan/koel"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "9.7.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54491"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-15T17:59:30Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\n\nThe fix for **CVE-2026-47260** (v9.3.5) added an **initial** `isSafeUrl()` check to several fetchers (`synchronizeEpisodes`, `getStreamableUrl`, `AddRadioStation`, `EpisodePlayable`), but the **redirect-target validation** \u2014 the per-hop Guzzle `on_redirect` callback added in follow-up commit `be1e867` \u2014 was applied to **only one** path, `EpisodePlayable`. Every other server-side fetcher therefore has **only the initial check, which an HTTP 302 redirect to an internal address bypasses**, or no check at all. **DNS rebinding** (validation and connection resolve DNS separately, with no IP pinning) bypasses the initial check on every path.\n\nAn **authenticated, non-admin** user can thus cause the Koel server to issue requests to arbitrary internal / cloud-metadata endpoints (SSRF) by supplying a URL on an attacker-controlled host that 302-redirects to an internal address.\n\n\u003e Note: commit `be1e867` shows the redirect-based SSRF vector was recognised, but the redirect defense was applied to a single call site rather than generalised \u2014 so the class survives in the sibling paths below.\n\n### Details \u2014 Root cause\n\n`App\\Helpers\\Network::isPublicHost()` / `isSafeUrl()` perform a **point-in-time host check** with no pinning of the resolved IP, and **per-redirect-hop** re-validation exists **only** in `App\\Values\\Podcast\\EpisodePlayable` (the `on_redirect` callback from commit `be1e867`). Consequently every other fetcher is exposed to (1) **redirect SSRF** \u2014 initial URL passes `isSafeUrl`, then the HTTP client follows a cross-host 302 to an internal target without re-validating the hop; and (2) **DNS rebinding (TOCTOU)** \u2014 `isPublicHost` resolves DNS at validation, the HTTP client resolves again at connect time.\n\n### Affected paths (all reachable by any authenticated user)\n\n| # | Location | Issue |\n|---|----------|-------|\n| 1 | `PhanAn\\Poddle\\Poddle::fromUrl()` \u2192 `Http::timeout()-\u003eget($url)` (used by `PodcastService::addPodcast`/`refreshPodcast`) | Plain `Http::get`, follows redirects, no per-hop validation; `refreshPodcast` does not re-run `isSafeUrl` at all |\n| 2 | `PodcastService::getStreamableUrl()` (`PodcastService.php:244`/`251`) | Has the initial `isSafeUrl()` (line 244) but the request uses `ALLOW_REDIRECTS =\u003e [\u0027track_redirects\u0027 =\u003e true]` with **no `on_redirect`** \u2192 302 to internal is followed. Called at episode stream time via `PodcastStreamerAdapter`. Also DNS-rebinding-exposed |\n| 3 | `PodcastService::isPodcastObsolete()` (`:221`) `Http::head($podcast-\u003eurl)` | No `isSafeUrl`, no redirect validation |\n| 4 | `App\\Rules\\HasAudioContentType` (`:45`/`:54`) `Http::head`/`Http::get` | Self-documented \"use after SafeUrl\"; ordering-dependent, no own validation, no per-hop check. Extends the surface to the **internet-radio** feature (`RadioStationStore/UpdateRequest`) |\n| 5 | `App\\Rules\\SafeUrl` validator (`:52`/`:56`) | Follows redirects, validates only the **final** effective host \u2014 intermediate-hop requests still fire |\n\nReachable via the native API (`apiResource podcasts`, `radio/stations`; `PodcastController::store` has **no authorization check**, only `#[DisabledInDemo]`) and the Subsonic API (`createPodcastChannel`, `createInternetRadioStation`, `refreshPodcasts`).\n\n### PoC\n\nA mechanism PoC that runs the exact Guzzle/Laravel-Http call shapes Koel uses (attacker-redirect server + internal-target listener on loopback), verified on PHP 8.2 + Guzzle 7:\n\n```\nisPublicHost(\u0027127.0.0.1\u0027) = false        # a per-hop check WOULD block this\nCase1 Poddle::fromUrl        -\u003e [VULNERABLE]  leaked INTERNAL-SECRET-TOKEN\nCase2 getStreamableUrl       -\u003e [VULNERABLE]  leaked INTERNAL-SECRET-TOKEN\nCase3 EpisodePlayable        -\u003e [BLOCKED]     UnsafeUrl on redirect\ninternal_hits.log: 2 hits    # internal service actually reached by Case1 + Case2\n```\n\nCase1/Case2 reaching the internal target while Case3 (the fixed path) blocks under identical conditions demonstrates the incomplete remediation. The full PoC kit (poc.php, attacker_router.php, internal_router.php) is available on request.\n\nEnd-to-end on a real instance: an authenticated user `POST /api/podcasts` (or Subsonic `createPodcastChannel`) with a feed URL on an attacker host that returns `302 Location: http://169.254.169.254/latest/meta-data/...` (or `http://127.0.0.1:\u003cport\u003e/`); the server follows it. The response is reflected back via parsed podcast fields / `getStreamableUrl` when the internal endpoint returns `Access-Control-Allow-Origin: *`; otherwise blind SSRF via status/timing.\n\n### Impact\n\nAuthenticated (any user) SSRF: access to cloud instance metadata (IAM credentials on IMDSv1), internal-only admin panels, and internal network service probing \u2014 from the Koel server\u0027s network position. Same threat model as CVE-2026-47260.\n\n**Attack scenario (fully remote, no user interaction):** the only precondition is a single low-privilege account. On AWS/GCP/Azure-hosted instances, redirecting to the metadata IP and reflecting the body discloses temporary IAM credentials \u2192 cloud-account pivot. (AWS IMDSv2\u0027s token-via-PUT is not reachable through a simple GET-redirect SSRF; IMDSv1 instances are fully exposed.) \"Koel only runs on an internal/trusted network\" does not reduce the risk \u2014 the bug makes the Koel server itself the attacker\u0027s pivot **into** that trusted network and cloud control plane.\n\nSuggested severity: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N (7.1); lower where exploitation is blind.\n\n### Remediation\n\nDo not fix per-call-site. Centralize: route **all** outbound HTTP through a shared Guzzle handler/middleware that, on **every** connection and **every redirect hop**, resolves the target and rejects private/reserved IPs, and **pins** the validated IP for the actual connection (defeats DNS rebinding). Apply to `EpisodePlayable`, `getStreamableUrl`, `Poddle::fromUrl` usage, `isPodcastObsolete`, `HasAudioContentType`, and the `SafeUrl` rule.",
  "id": "GHSA-6qvr-wjmv-v8mm",
  "modified": "2026-07-15T17:59:30Z",
  "published": "2026-07-15T17:59:30Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/koel/koel/security/advisories/GHSA-6qvr-wjmv-v8mm"
    },
    {
      "type": "WEB",
      "url": "https://github.com/koel/koel/pull/2546"
    },
    {
      "type": "WEB",
      "url": "https://github.com/koel/koel/pull/2549"
    },
    {
      "type": "WEB",
      "url": "https://github.com/koel/koel/commit/5f6ce2cefd08f437a269236b677ad971517ccbb6"
    },
    {
      "type": "WEB",
      "url": "https://github.com/koel/koel/commit/c264a3d52513a83b21e1cc3a20e895caea97fc4a"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/koel/koel"
    },
    {
      "type": "WEB",
      "url": "https://github.com/koel/koel/releases/tag/v9.7.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Koel: Incomplete fix for CVE-2026-47260 \u2014 systemic SSRF in podcast \u0026 radio fetch paths"
}

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.