Skip to content

fix(yurthub): reject unauthenticated requests on insecure proxy port - #2783

Open
sultancodesss wants to merge 1 commit into
openyurtio:masterfrom
sultancodesss:fix/yurthub-unauthenticated-proxy-credential-leak
Open

fix(yurthub): reject unauthenticated requests on insecure proxy port#2783
sultancodesss wants to merge 1 commit into
openyurtio:masterfrom
sultancodesss:fix/yurthub-unauthenticated-proxy-credential-leak

Conversation

@sultancodesss

Copy link
Copy Markdown

What this PR does

Fixes #2782

Problem

When --enable-dummy-if=true (the default), YurtHub exposes a plain-HTTP proxy on 127.0.0.1:10261 (and 169.254.2.1:10261 for the dummy interface). The proxy handler has no authentication layer on this port.

In RemoteProxy.RoundTrip, requests that carry no Authorization header are forwarded to the Kubernetes API using YurtHub's own node client certificate:

func (rp *RemoteProxy) RoundTrip(req *http.Request) (*http.Response, error) {
    if isBearerRequest(req) {
        return rp.bearerTransport.RoundTrip(req)  // uses bearer token from request
    }
    return rp.currentTransport.RoundTrip(req)     // uses YurtHub's node cert (the bug)
}

Any pod that can route traffic to the dummy IP can therefore cause Kubernetes API calls authenticated as system:node:<node> without supplying any credentials.

Fix

Add a WithRequireAuthorization middleware in pkg/yurthub/proxy/util/util.go that returns 401 Unauthorized for any request arriving on the plain-HTTP proxy port without an Authorization header.

The middleware is wired in pkg/yurthub/server/server.go exclusively for the insecure proxy serving path (YurtHubProxyServerServing). The secure TLS port (YurtHubSecureProxyServerServing) is unaffected -- it already enforces mutual TLS client certificate authentication.

YurtHub's own internal clients are explicitly exempted to preserve existing behaviour:

  • The multiplexer manager client (User-Agent: multiplexer-proxy-<node>)
  • The shared-informer clients (User-Agent prefix: yurthub)

Testing

Both modified packages build cleanly for linux/amd64:

GOOS=linux GOARCH=amd64 go build ./pkg/yurthub/proxy/util/
GOOS=linux GOARCH=amd64 go build ./pkg/yurthub/server/
GOOS=linux GOARCH=amd64 go build ./cmd/yurthub/...

Related

Without this fix, RemoteProxy.RoundTrip forwards any request that
lacks an Authorization header using YurtHub's own node client
certificate. This means any pod able to reach the plain-HTTP proxy
(127.0.0.1:10261 / 169.254.2.1:10261) can make Kubernetes API
requests authenticated as system:node:<node> without supplying any
credentials of its own.

Fix: add a WithRequireAuthorization middleware that is applied
exclusively to the insecure (plain-HTTP) proxy serving path in
RunYurtHubServers. The middleware returns 401 Unauthorized for any
request that carries no Authorization header, closing the credential-
lending path in RemoteProxy.RoundTrip.

YurtHub's own internal clients (multiplexer-proxy-<node> and the
shared-informer clients with User-Agent prefix 'yurthub') are
explicitly exempted so existing internal communication is unaffected.

Fixes: openyurtio#2782
@sultancodesss
sultancodesss requested a review from a team as a code owner August 29, 2026 07:34
@sonarqubecloud

Copy link
Copy Markdown

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.

Unauthenticated HTTP proxy on the dummy interface hands YurtHub's node identity to any pod

1 participant