fix(nat): scrub dashboard-issued credentials from all accepted token channels

The initial selective strip covered only the Authorization header, but the
dashboard also accepts its JWT via the ?token= query parameter and the
nz-jwt cookie (jwt.go TokenLookup channels). A dashboard credential arriving
through those channels would still reach a NAT backend.

Apply the same classify-then-strip rule to all three channels at NAT
ingress: values verified as dashboard-issued are removed, foreign values
are preserved byte-for-byte. Adds a ServeNAT flow test exercising the live
classifier and a wiring test pinning the gate injection in main().
This commit is contained in:
xvkong233 authored and naiba committed 2026-10-01 11:17:45 +00:00
1 parent 40240ed02b
commit 3ad985f36e
12 files changed
+806 -82

No files matched your search

+5 -4
View File
@@ -19,10 +19,11 @@ type natCapabilityLease struct {
func prepareNATCapability(request *http.Request, _ *model.NAT) (natCapabilityLease, error) {
// The default build has no capability protocol: every request takes the
// legacy NAT path, so any dashboard-issued Authorization value (panel JWT
// or panel PAT) is stripped before the request is tunneled to the agent.
// Foreign Authorization values are ordinary request data and stay put.
stripDashboardCredential(request)
// legacy NAT path, so any dashboard-issued credential (panel JWT or panel
// PAT) carried by the Authorization header, the ?token= query parameter or
// the nz-jwt cookie is stripped before the request is tunneled to the
// agent. Foreign values are ordinary request data and stay put.
stripDashboardCredentials(request)
return natCapabilityLease{}, nil
}