Files
traefikoidc/review_r166_regression_test.go
T
lukaszraczylo 6d96e8869b test: add R-round regression and security suite
- fail-on-old regression tests for every shipped fix (R-rounds)
- fuzz targets (parseJWT, bearer), concurrency-stress, shuffle-flake guards
- coverage-closing contract tests (health-check backend, TLS-posture reuse)
- r154 ID-token fixture built from parts to avoid false-positive secret scan
2026-08-14 16:22:39 +01:00

56 lines
2.0 KiB
Go

package traefikoidc
import (
"encoding/json"
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
)
// TestR166_BearerOpaqueWithTwoDotsIntrospected guards the JWT-vs-opaque
// routing gate in handleBearerRequest (bearer_auth.go). Previously the
// gate used only strings.Count(token, ".") == 2, so an opaque token
// that coincidentally contained exactly two dots was routed onto the
// JWT path, its header failed to parse, and it was rejected with 401
// even when requireTokenIntrospection was enabled (whose purpose is
// exactly opaque-token support). The gate now treats a token as a JWT
// only when its header actually parses as a JOSE header, so an opaque
// token with coincidental dots is introspected like any other.
// Fail-on-old: an opaque token with exactly two dots is rejected (401),
// never introspected, when requireTokenIntrospection is set.
func TestR166_BearerOpaqueWithTwoDotsIntrospected(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"active": true,
"sub": "opaque-two-dots",
"token_type": "Bearer",
})
}))
defer ts.Close()
var nextCalled atomic.Bool
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
nextCalled.Store(true)
w.WriteHeader(http.StatusOK)
})
oidc := makeBearerOIDC(t, next)
oidc.requireTokenIntrospection = true
oidc.introspectionURL = ts.URL
oidc.httpClient = ts.Client()
oidc.clientSecret = "secret"
// Opaque token with exactly two dots, but its first segment is not a
// decodable JOSE header (so it is not a JWT, only looks like one).
req := httptest.NewRequest("GET", "/api/x", nil)
req.Header.Set("Authorization", "Bearer a.b.c")
rw := httptest.NewRecorder()
oidc.ServeHTTP(rw, req)
if !nextCalled.Load() {
t.Fatalf("opaque token containing exactly two dots must be introspected and forwarded when requireTokenIntrospection is set; status=%d body=%q", rw.Code, rw.Body.String())
}
}