Default kuma-cp leaks admin token cross-origin via CORS wildcard + LocalhostIsAdmin
Description
Summary
Default kuma-cp config leaks the admin bootstrap token and signing keys to any webpage the operator visits while the control plane is reachable from their browser. CorsAllowedDomains: [".*"] reflects any Origin, and LocalhostIsAdmin: true promotes requests from 127.0.0.1 to mesh-system:admin. A cross-origin fetch() from a malicious page returns the admin JWT and signing material.
Am
I affected?
You are affected if all of these hold:
1. kuma-cp runs with default config (CorsAllowedDomains: [".*"] and LocalhostIsAdmin: true). 2. The control plane is reachable from a browser on the same machine: - kuma-cp run on a developer laptop - Docker --network host or port-publish on a workstation - kubectl port-forward from a machine that also browses the web 3. The operator visits a page running attacker JavaScript while the control plane is reachable.
You are not affected if:
- The control plane runs on a Kubernetes cluster accessed via ClusterIP, NodePort, or LoadBalancer from a remote client.
- The control plane runs on an SSH-administered VM with no browser on the host.
KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN=falseis set (see https://kuma.io/docs/latest/production/secure-deployment/api-server-auth/).KUMA_API_SERVER_CORS_ALLOWED_DOMAINSis set to an explicit allowlist that excludes attacker origins.
Mitigation
- Set
KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN=falseafter retrieving the admin token. - Set
KUMA_API_SERVER_CORS_ALLOWED_DOMAINSto an explicit allowlist, for examplehttp://localhost:5681,http://127.0.0.1:5681. - Do not run
kuma-cpon a machine where you browse untrusted sites.
Fix
Fixed in #16416, backported to all supported release branches (#16423, #16424, #16425, #16426, #16427).
Changes in patched versions:
CorsAllowedDomainsdefault changed from[".*"]to[]— CORS is now opt-in; set the env var explicitly if you need GUI access.LocalhostIsAdminhardened: now requires direct loopbackRemoteAddrandHost, and rejects requests carrying proxy-hop headers (X-Forwarded-For), cross-site fetch metadata (Sec-Fetch-Site), or a non-localhostOrigin.
Upgrade to a patched version:
- 2.7.25
- 2.9.15
- 2.11.13
- 2.12.10
- 2.13.5
Credits
Reported by eldudareeno.
CVSS
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N = 5.1 Medium.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Default kuma-cp configuration with CORS wildcard and localhost admin authentication allows cross-origin theft of admin tokens and signing keys.
Vulnerability
CVE-2026-45021 arises from two default configuration settings in the Kuma control plane (kuma-cp). The CorsAllowedDomains is set to [".*"], which reflects any Origin header, and LocalhostIsAdmin is set to true, which promotes requests from 127.0.0.1 to mesh-system:admin [1][3]. This combination allows a malicious webpage visited by an operator on the same machine to make cross-origin fetch() requests to the control plane, which are treated as admin requests and return the admin JWT and signing material [2][4].
Exploitation
An attacker can exploit this vulnerability if the operator runs kuma-cp on a machine where they also browse the web, such as a developer laptop, a Docker container with --network host, or a kubectl port-forward session [3][4]. The attacker's JavaScript can send a cross-origin request to the control plane, which, due to the CORS wildcard, will include the response. The LocalhostIsAdmin setting then authenticates the request as admin because it originates from the loopback address, even though it is a cross-origin request from a different origin [1][2].
Impact
Successful exploitation allows an attacker to obtain the admin bootstrap token and signing keys, granting full administrative access to the Kuma control plane [3][4]. This could lead to complete compromise of the service mesh configuration, including the ability to modify policies, intercept traffic, or disrupt mesh operations.
Mitigation
The vulnerability is fixed in Kuma versions 2.7.25, 2.9.15, 2.11.13, 2.12.10, and 2.13.5 [3][4]. The fix changes the default CorsAllowedDomains to an empty list, making CORS opt-in, and hardens the LocalhostIsAdmin check to require direct loopback connections and reject requests with proxy-hop headers or cross-site fetch metadata [1][2]. Operators should also set KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN=false after retrieving the admin token and configure an explicit CORS allowlist [3][4].
AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/kumahq/kumaGo | < 2.7.25 | 2.7.25 |
github.com/kumahq/kumaGo | >= 2.9.0, < 2.9.15 | 2.9.15 |
github.com/kumahq/kumaGo | >= 2.11.0, < 2.11.13 | 2.11.13 |
github.com/kumahq/kumaGo | >= 2.12.0, < 2.12.10 | 2.12.10 |
github.com/kumahq/kumaGo | >= 2.13.0, < 2.13.5 | 2.13.5 |
Affected products
2Patches
18fefa8595d44fix(api-server): harden localhost admin auth (#16416)
11 files changed · +366 −18
docs/generated/raw/kuma-cp.yaml+1 −2 modified@@ -200,8 +200,7 @@ apiServer: # If true, then API Server will operate in read only mode (serving GET requests) readOnly: false # ENV: KUMA_API_SERVER_READ_ONLY # Allowed domains for Cross-Origin Resource Sharing. The value can be either domain or regexp - corsAllowedDomains: - - ".*" # ENV: KUMA_API_SERVER_CORS_ALLOWED_DOMAINS + corsAllowedDomains: [] # ENV: KUMA_API_SERVER_CORS_ALLOWED_DOMAINS # Can be used if you use a reverse proxy rootUrl: "" # ENV: KUMA_API_SERVER_ROOT_URL # The path to serve the API from
pkg/api-server/api_server_suite_test.go+2 −0 modified@@ -71,6 +71,8 @@ func NewTestApiServerConfigurer() *testApiServerConfigurer { store: memory.NewStore(), } t.config.GUI.Enabled = false + t.config.HTTP.Interface = "127.0.0.1" + t.config.HTTPS.Interface = "127.0.0.1" return t }
pkg/api-server/authn/authn_suite_test.go+11 −0 added@@ -0,0 +1,11 @@ +package authn_test + +import ( + "testing" + + "github.com/kumahq/kuma/v2/pkg/test" +) + +func TestAuthn(t *testing.T) { + test.RunSpecs(t, "Authn Suite") +}
pkg/api-server/authn/localhost.go+143 −8 modified@@ -2,25 +2,160 @@ package authn import ( "net" + "net/http" + "net/url" + "strconv" + "strings" "github.com/emicklei/go-restful/v3" "github.com/kumahq/kuma/v2/pkg/core" - rest_errors "github.com/kumahq/kuma/v2/pkg/core/rest/errors" "github.com/kumahq/kuma/v2/pkg/core/user" ) var log = core.Log.WithName("api-server").WithName("authn") func LocalhostAuthenticator(request *restful.Request, response *restful.Response, chain *restful.FilterChain) { - host, _, err := net.SplitHostPort(request.Request.RemoteAddr) - if err != nil { - rest_errors.HandleError(request.Request.Context(), response, err, "Could not parse Remote Address from the Request") - return - } - if host == "127.0.0.1" || host == "::1" { - log.V(1).Info("authenticated as admin because requests originates from the same machine") + if isDirectLoopbackRequest(request.Request) { + log.V(1).Info("authenticated as admin because request is a direct localhost call") request.Request = request.Request.WithContext(user.Ctx(request.Request.Context(), user.Admin.Authenticated())) } chain.ProcessFilter(request, response) } + +// isDirectLoopbackRequest returns true only when all conditions hold: +// - RemoteAddr is a loopback address, +// - no proxy-hop headers are present (Forwarded, X-Forwarded-For, X-Real-IP), +// - the Host header is localhost or a loopback address, +// - the browser did not mark the request as cross-site, and +// - if an Origin header is present it is same-origin with the Host. +// +// This prevents browsers on the same machine, which connect over loopback, +// from triggering admin access on behalf of a non-localhost origin. +func isDirectLoopbackRequest(r *http.Request) bool { + remoteHost, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil || !isLoopbackHost(remoteHost) { + return false + } + if hasProxyHeaders(r.Header) { + return false + } + if !isLoopbackRequestHost(r.Host) { + return false + } + switch r.Header.Get("Sec-Fetch-Site") { + case "", "same-origin", "none": + default: + return false + } + return isSameOriginLoopback(r.Header.Get("Origin"), r.Host) +} + +func isLoopbackHost(host string) bool { + host = strings.TrimSuffix(strings.ToLower(host), ".") + if host == "localhost" { + return true + } + if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") { + host = strings.TrimPrefix(strings.TrimSuffix(host, "]"), "[") + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} + +func isLoopbackRequestHost(hostport string) bool { + host, _, ok := parseAuthority("http", hostport) + if !ok { + return false + } + return isLoopbackHost(host) +} + +func hasProxyHeaders(h http.Header) bool { + return h.Get("Forwarded") != "" || h.Get("X-Forwarded-For") != "" || h.Get("X-Real-IP") != "" +} + +func isSameOriginLoopback(origin, requestHost string) bool { + if origin == "" { + return true + } + u, err := url.Parse(origin) + if err != nil || u.Host == "" { + return false + } + if u.Scheme != "http" && u.Scheme != "https" { + return false + } + if !isLoopbackHost(u.Hostname()) { + return false + } + originHost, originPort, ok := parseOrigin(u) + if !ok { + return false + } + host, port, ok := parseAuthority(u.Scheme, requestHost) + if !ok { + return false + } + return originHost == host && originPort == port +} + +func parseOrigin(u *url.URL) (string, string, bool) { + if u.User != nil || u.Host == "" || u.Path != "" || u.RawQuery != "" || u.Fragment != "" { + return "", "", false + } + if strings.HasSuffix(u.Host, ":") { + return "", "", false + } + return parseURLAuthority(u) +} + +func parseAuthority(scheme, hostport string) (string, string, bool) { + if strings.HasSuffix(hostport, ":") { + return "", "", false + } + u, err := url.Parse(scheme + "://" + hostport) + if err != nil || u.User != nil || u.Host == "" || u.Path != "" || u.RawQuery != "" || u.Fragment != "" { + return "", "", false + } + return parseURLAuthority(u) +} + +func parseURLAuthority(u *url.URL) (string, string, bool) { + port := u.Port() + if port == "" { + port = defaultPort(u.Scheme) + } + if !validPort(port) { + return "", "", false + } + host := canonicalHost(u.Hostname()) + if host == "" { + return "", "", false + } + return host, port, true +} + +func canonicalHost(host string) string { + host = strings.TrimSuffix(strings.ToLower(host), ".") + ip := net.ParseIP(host) + if ip != nil { + return ip.String() + } + return host +} + +func defaultPort(scheme string) string { + switch scheme { + case "http": + return "80" + case "https": + return "443" + } + return "" +} + +func validPort(port string) bool { + n, err := strconv.Atoi(port) + return err == nil && n > 0 && n <= 65535 +}
pkg/api-server/authn/localhost_test.go+122 −0 added@@ -0,0 +1,122 @@ +package authn_test + +import ( + "context" + "net/http" + "net/http/httptest" + + "github.com/emicklei/go-restful/v3" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/kumahq/kuma/v2/pkg/api-server/authn" + "github.com/kumahq/kuma/v2/pkg/core/user" +) + +// runLocalhost runs LocalhostAuthenticator with the given request parameters +// and returns the name of the resulting user from context. +func runLocalhost(remoteAddr, host, origin string, extraHeaders map[string]string) string { + req := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "http://localhost/test", http.NoBody) + req.RemoteAddr = remoteAddr + req.Host = host + if origin != "" { + req.Header.Set("Origin", origin) + } + for k, v := range extraHeaders { + req.Header.Set(k, v) + } + + rr := httptest.NewRecorder() + restfulReq := &restful.Request{Request: req} + restfulResp := restful.NewResponse(rr) + + chain := &restful.FilterChain{ + Target: func(_ *restful.Request, _ *restful.Response) {}, + } + authn.LocalhostAuthenticator(restfulReq, restfulResp, chain) + + return user.FromCtx(restfulReq.Request.Context()).Name +} + +var _ = Describe("LocalhostAuthenticator", func() { + DescribeTable("direct loopback requests", + func(remoteAddr, host, origin string, extraHeaders map[string]string, expectAdmin bool) { + name := runLocalhost(remoteAddr, host, origin, extraHeaders) + if expectAdmin { + Expect(name).To(Equal(user.Admin.Name)) + } else { + Expect(name).NotTo(Equal(user.Admin.Name)) + } + }, + // Admin-granted cases + Entry("direct loopback IPv4, no Origin", + "127.0.0.1:54321", "localhost:5681", "", nil, true), + Entry("direct loopback IPv6, no Origin", + "[::1]:54321", "localhost:5681", "", nil, true), + Entry("direct loopback IPv6 Host without explicit port", + "[::1]:54321", "[::1]", "", nil, true), + Entry("direct loopback, same-origin http://localhost", + "127.0.0.1:54321", "localhost:5681", "http://localhost:5681", nil, true), + Entry("direct loopback, same-origin http://127.0.0.1", + "127.0.0.1:54321", "127.0.0.1:5681", "http://127.0.0.1:5681", nil, true), + Entry("direct loopback, same-origin Host case", + "127.0.0.1:54321", "LOCALHOST:5681", "http://localhost:5681", nil, true), + Entry("direct loopback, same-origin implicit HTTP default port", + "127.0.0.1:54321", "localhost:80", "http://localhost", nil, true), + Entry("direct loopback, same-origin implicit HTTPS default port", + "127.0.0.1:54321", "localhost:443", "https://localhost", nil, true), + Entry("direct loopback, same-origin explicit origin HTTP default port", + "127.0.0.1:54321", "localhost", "http://localhost:80", nil, true), + Entry("direct loopback, same-origin bracketed IPv6 default port", + "[::1]:54321", "[::1]:80", "http://[::1]", nil, true), + Entry("direct loopback, same-origin bracketed IPv6 explicit origin default port", + "[::1]:54321", "[::1]", "http://[::1]:80", nil, true), + Entry("direct loopback with same-origin fetch metadata", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"Sec-Fetch-Site": "same-origin"}, true), + Entry("direct loopback with user-initiated fetch metadata", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"Sec-Fetch-Site": "none"}, true), + // Blocked cases + Entry("cross-origin evil.com", + "127.0.0.1:54321", "localhost:5681", "https://evil.com", nil, false), + Entry("cross-site browser request without Origin", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"Sec-Fetch-Site": "cross-site"}, false), + Entry("same-site browser request without Origin", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"Sec-Fetch-Site": "same-site"}, false), + Entry("cross-origin local app on different port", + "127.0.0.1:54321", "localhost:5681", "http://127.0.0.1:3000", nil, false), + Entry("cross-origin implicit HTTP default port to non-default request port", + "127.0.0.1:54321", "localhost:5681", "http://localhost", nil, false), + Entry("cross-origin implicit HTTPS default port to non-default request port", + "127.0.0.1:54321", "localhost:5682", "https://localhost", nil, false), + Entry("cross-origin explicit non-default origin port to implicit request port", + "127.0.0.1:54321", "localhost", "http://localhost:5681", nil, false), + Entry("X-Forwarded-For header present", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"X-Forwarded-For": "1.2.3.4"}, false), + Entry("Forwarded header present", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"Forwarded": "for=1.2.3.4"}, false), + Entry("X-Real-IP header present", + "127.0.0.1:54321", "localhost:5681", "", map[string]string{"X-Real-IP": "1.2.3.4"}, false), + Entry("non-loopback Host (reverse proxy public domain)", + "127.0.0.1:54321", "api.example.com", "", nil, false), + Entry("malformed bracketed IPv6 Host", + "[::1]:54321", "[::1", "", nil, false), + Entry("malformed Host port", + "127.0.0.1:54321", "localhost:bad", "", nil, false), + Entry("empty Host port", + "127.0.0.1:54321", "localhost:", "", nil, false), + Entry("Origin: null", + "127.0.0.1:54321", "localhost:5681", "null", nil, false), + Entry("malformed Origin", + "127.0.0.1:54321", "localhost:5681", "not-a-url", nil, false), + Entry("malformed Origin port", + "127.0.0.1:54321", "localhost:5681", "http://localhost:bad", nil, false), + Entry("Origin with path", + "127.0.0.1:54321", "localhost:5681", "http://localhost:5681/path", nil, false), + Entry("Origin with query", + "127.0.0.1:54321", "localhost:5681", "http://localhost:5681?x=1", nil, false), + Entry("Origin with userinfo", + "127.0.0.1:54321", "localhost:5681", "http://user@localhost:5681", nil, false), + Entry("remote RemoteAddr is not granted admin", + "203.0.113.1:54321", "localhost:5681", "", nil, false), + ) +})
pkg/api-server/auth_test.go+43 −0 modified@@ -120,6 +120,49 @@ var _ = Describe("Auth test", func() { Expect(rr.Body.Bytes()).To(matchers.MatchGoldenJSON(path.Join("testdata", "auth-admin-https-bad-creds.golden.json"))) }) + It("should block admin access when Origin is a cross-origin domain", func() { + // This simulates a browser fetch() from evil.com to localhost:5681. + // The browser connects over loopback, but the Origin header reveals a + // non-localhost origin. LocalhostAuthenticator must NOT grant admin. + req := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "/secrets", http.NoBody) + req.RemoteAddr = "127.0.0.1:54321" + req.Host = fmt.Sprintf("localhost:%d", httpPort) + req.Header.Set("Origin", "https://evil.com") + rr := httptest.NewRecorder() + apiServer.Handler().ServeHTTP(rr, req) + + // then + Expect(rr.Code).To(Equal(403)) + }) + + It("should grant admin when Origin is same-origin localhost (GUI use case)", func() { + // Simulates the Kuma GUI: browser on localhost fetching from the same + // localhost:port. Origin matches Host, so admin should be granted. + req := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "/secrets", http.NoBody) + req.RemoteAddr = "127.0.0.1:54321" + req.Host = fmt.Sprintf("localhost:%d", httpPort) + req.Header.Set("Origin", fmt.Sprintf("http://localhost:%d", httpPort)) + rr := httptest.NewRecorder() + apiServer.Handler().ServeHTTP(rr, req) + + // then + Expect(rr.Code).To(Equal(200)) + }) + + It("should block admin when a proxy header is present on a loopback request", func() { + // X-Forwarded-For on a loopback-sourced request signals a reverse proxy + // laundering remote traffic. Admin must be denied. + req := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "/secrets", http.NoBody) + req.RemoteAddr = "127.0.0.1:54321" + req.Host = fmt.Sprintf("localhost:%d", httpPort) + req.Header.Set("X-Forwarded-For", "203.0.113.1") + rr := httptest.NewRecorder() + apiServer.Handler().ServeHTTP(rr, req) + + // then + Expect(rr.Code).To(Equal(403)) + }) + It("should be able to access config on localhost using HTTP", func() { // when resp, err := http.Get(fmt.Sprintf("http://localhost:%d/config", httpPort))
pkg/api-server/resource_endpoints_test.go+3 −0 modified@@ -15,6 +15,7 @@ import ( mesh_proto "github.com/kumahq/kuma/v2/api/mesh/v1alpha1" api_server "github.com/kumahq/kuma/v2/pkg/api-server" + config "github.com/kumahq/kuma/v2/pkg/config/api-server" core_meta "github.com/kumahq/kuma/v2/pkg/core/metadata" core_mesh "github.com/kumahq/kuma/v2/pkg/core/resources/apis/mesh" meshexternalservice_api "github.com/kumahq/kuma/v2/pkg/core/resources/apis/meshexternalservice/api/v1alpha1" @@ -59,6 +60,8 @@ var _ = Describe("Resource Endpoints", func() { m, _ := core_metrics.NewMetrics("Zone") metrics = m return m + }).WithConfigMutator(func(cfg *config.ApiServerConfig) { + cfg.CorsAllowedDomains = []string{".*"} })) })
pkg/api-server/server.go+7 −5 modified@@ -126,12 +126,14 @@ func NewApiServer( } container.Filter(rt.APIServerAuthenticator()) - cors := restful.CrossOriginResourceSharing{ - ExposeHeaders: []string{restful.HEADER_AccessControlAllowOrigin}, - AllowedDomains: serverConfig.CorsAllowedDomains, - Container: container, + if len(serverConfig.CorsAllowedDomains) > 0 { + cors := restful.CrossOriginResourceSharing{ + ExposeHeaders: []string{restful.HEADER_AccessControlAllowOrigin}, + AllowedDomains: serverConfig.CorsAllowedDomains, + Container: container, + } + container.Filter(cors.Filter) } - container.Filter(cors.Filter) // We create a WebService and set up resources endpoints and index endpoint instead of creating WebService // for every resource like /meshes/{mesh}/traffic-permissions, /meshes/{mesh}/traffic-log etc.
pkg/config/api-server/config.go+1 −1 modified@@ -243,7 +243,7 @@ func (a *ApiServerConfig) Validate() error { func DefaultApiServerConfig() *ApiServerConfig { return &ApiServerConfig{ ReadOnly: false, - CorsAllowedDomains: []string{".*"}, + CorsAllowedDomains: []string{}, BasePath: "/", HTTP: ApiServerHTTPConfig{ Enabled: true,
pkg/config/app/kuma-cp/kuma-cp.defaults.yaml+1 −2 modified@@ -200,8 +200,7 @@ apiServer: # If true, then API Server will operate in read only mode (serving GET requests) readOnly: false # ENV: KUMA_API_SERVER_READ_ONLY # Allowed domains for Cross-Origin Resource Sharing. The value can be either domain or regexp - corsAllowedDomains: - - ".*" # ENV: KUMA_API_SERVER_CORS_ALLOWED_DOMAINS + corsAllowedDomains: [] # ENV: KUMA_API_SERVER_CORS_ALLOWED_DOMAINS # Can be used if you use a reverse proxy rootUrl: "" # ENV: KUMA_API_SERVER_ROOT_URL # The path to serve the API from
UPGRADE.md+32 −0 modified@@ -32,7 +32,39 @@ Or via environment variable: `KUMA_DNS_SERVER_DOMAIN=mesh` Review your `HostnameGenerator` resources and ensure their `spec.template` values produce valid [RFC 1123](https://tools.ietf.org/html/rfc1123) DNS subdomains for all inputs. +### localhost-admin is restricted to direct loopback; CORS is now opt-in +The defaults have been tightened: + +- `LocalhostIsAdmin` still defaults to `true`, but only direct loopback requests are promoted to admin. +- `CorsAllowedDomains` now defaults to `[]` / empty (was `[".*"]`). + +The `LocalhostIsAdmin` restriction also applies to release branches as a security fix: the authenticator now only grants admin when the request is a **direct** loopback call (loopback `RemoteAddr`, loopback `Host`, no proxy-hop headers, and a matching `Origin` if present). Browsers connecting over loopback from a non-localhost page are no longer promoted to admin. + +**Action required:** + +_Local bootstrap / development (Universal mode)_ + +If you rely on `LocalhostIsAdmin` for initial kumactl setup, keep using direct loopback access or switch to token-based authentication with `kumactl config control-planes add --auth-type=tokens`. + +_Reverse-proxy / CORS users_ + +If your deployment relies on cross-origin API access (e.g., a custom GUI on a different port), set the allowed domains explicitly: + +```yaml +# kuma-cp config +apiServer: + corsAllowedDomains: + - "https://my-gui.example.com" +``` + +or via environment variable: + +```sh +KUMA_API_SERVER_CORS_ALLOWED_DOMAINS=https://my-gui.example.com +``` + +The Helm chart already sets `KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN=false` and is not affected by the `LocalhostIsAdmin` default. ### CPU limits removed from `kuma-init` and `kuma-sidecar` containers
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
9- github.com/advisories/GHSA-3vcp-chfh-f6r2ghsaADVISORY
- github.com/kumahq/kuma/commit/8fefa8595d44eb68d922405702ed7a0826322907ghsaWEB
- github.com/kumahq/kuma/pull/16416ghsaWEB
- github.com/kumahq/kuma/pull/16423ghsaWEB
- github.com/kumahq/kuma/pull/16424ghsaWEB
- github.com/kumahq/kuma/pull/16425ghsaWEB
- github.com/kumahq/kuma/pull/16426ghsaWEB
- github.com/kumahq/kuma/pull/16427ghsaWEB
- github.com/kumahq/kuma/security/advisories/GHSA-3vcp-chfh-f6r2ghsaWEB
News mentions
0No linked articles in our index yet.