Skip to content

Commit 66a676e

Browse files
Tenerprobakowski
andauthored
Switch to forked httprouter and enable UseRawPath option (#11068)
* Use forked httprouter with RawPath fix: gravitational/httprouter * Enable UseRawPath everywhere. * Test: allow MFA devices with `/` in names to be deleted Co-authored-by: Przemko Robakowski <przemko.robakowski@goteleport.com>
1 parent 0d702e6 commit 66a676e

8 files changed

Lines changed: 58 additions & 3 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ replace (
272272
github.com/go-redis/redis/v8 => github.com/gravitational/redis/v8 v8.11.5-0.20220211010318-7af711b76a91
273273
github.com/gogo/protobuf => github.com/gravitational/protobuf v1.3.2-0.20201123192827-2b9fcfaffcbf
274274
github.com/gravitational/teleport/api => ./api
275+
github.com/julienschmidt/httprouter => github.com/gravitational/httprouter v1.3.1-0.20220408074523-c876c5e705a5
275276
github.com/keys-pub/go-libfido2 => github.com/gravitational/go-libfido2 v1.5.3-0.20220412221142-6da2a1c840d1
276277
github.com/russellhaering/gosaml2 => github.com/gravitational/gosaml2 v0.0.0-20220318224559-f06932032ae2
277278
github.com/siddontang/go-mysql v1.1.0 => github.com/gravitational/go-mysql v1.1.1-teleport.2

go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,8 @@ github.com/gravitational/go-oidc v0.0.6 h1:DCllahGYxDAvxWsq8UILgO+/i1EheQRxcNzS+
504504
github.com/gravitational/go-oidc v0.0.6/go.mod h1:SevmOUNdOB0aD9BAIgjptZ6oHkKxMZZgA70nwPfgU/w=
505505
github.com/gravitational/gosaml2 v0.0.0-20220318224559-f06932032ae2 h1:8z1D1fehTDV20wkiGX+JTnlevvEUeVEh4LCygvOrFBs=
506506
github.com/gravitational/gosaml2 v0.0.0-20220318224559-f06932032ae2/go.mod h1:PiLt5KX4EMjlMIq3WLRR/xb5yqhiwtQhGr8wmU0b08M=
507+
github.com/gravitational/httprouter v1.3.1-0.20220408074523-c876c5e705a5 h1:qg8FcGwRACSHortU1UxCSo9nF0t34rPWjk9Nef3j2Ic=
508+
github.com/gravitational/httprouter v1.3.1-0.20220408074523-c876c5e705a5/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
507509
github.com/gravitational/kingpin v2.1.11-0.20190130013101-742f2714c145+incompatible h1:CfyZl3nyo9K5lLqOmqvl9/IElY1UCnOWKZiQxJ8HKdA=
508510
github.com/gravitational/kingpin v2.1.11-0.20190130013101-742f2714c145+incompatible/go.mod h1:LWxG30M3FcrjhOn3T4zz7JmBoQJ45MWZmOXgy9Ganoc=
509511
github.com/gravitational/license v0.0.0-20210218173955-6d8fb49b117a h1:PN5vAN1ZA0zqdpM6wNdx6+bkdlQ5fImd75oaIHSbOhY=
@@ -669,9 +671,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
669671
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
670672
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
671673
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
672-
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
673-
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
674-
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
675674
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
676675
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
677676
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=

lib/auth/apiserver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) {
8888
Clock: clockwork.NewRealClock(),
8989
}
9090
srv.Router = *httprouter.New()
91+
srv.Router.UseRawPath = true
9192

9293
// Kubernetes extensions
9394
srv.POST("/:version/kube/csr", srv.withAuth(srv.processKubeCSR))

lib/httplib/httplib_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ type testHandler struct {
6262
func newTestHandler() *testHandler {
6363
h := &testHandler{}
6464
h.Router = *httprouter.New()
65+
h.Router.UseRawPath = true
6566
h.POST("/v1/sessions/:id/stream", MakeHandler(h.postSessionChunkOriginal))
6667
h.POST("/v1/namespaces/:namespace/sessions/:id/stream", MakeHandler(h.postSessionChunkNamespace))
6768
return h

lib/kube/proxy/forwarder.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ func NewForwarder(cfg ForwarderConfig) (*Forwarder, error) {
245245
},
246246
}
247247

248+
fwd.router.UseRawPath = true
249+
248250
fwd.router.POST("/api/:ver/namespaces/:podNamespace/pods/:podName/exec", fwd.withAuth(fwd.exec))
249251
fwd.router.GET("/api/:ver/namespaces/:podNamespace/pods/:podName/exec", fwd.withAuth(fwd.exec))
250252

lib/web/apiserver.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*APIHandler, error) {
230230
ClusterFeatures: cfg.ClusterFeatures,
231231
}
232232

233+
// for properly handling url-encoded parameter values.
234+
h.UseRawPath = true
235+
233236
for _, o := range opts {
234237
if err := o(h); err != nil {
235238
return nil, trace.Wrap(err)

lib/web/apiserver_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,6 +2391,53 @@ func TestAddMFADevice(t *testing.T) {
23912391
}
23922392
}
23932393

2394+
func TestDeleteMFA(t *testing.T) {
2395+
t.Parallel()
2396+
ctx := context.Background()
2397+
env := newWebPack(t, 1)
2398+
proxy := env.proxies[0]
2399+
pack := proxy.authPack(t, "foo@example.com")
2400+
2401+
//setting up client manually because we need sanitizer off
2402+
jar, err := cookiejar.New(nil)
2403+
require.NoError(t, err)
2404+
opts := []roundtrip.ClientParam{roundtrip.BearerAuth(pack.session.Token), roundtrip.CookieJar(jar), roundtrip.HTTPClient(client.NewInsecureWebClient())}
2405+
rclt, err := roundtrip.NewClient(proxy.webURL.String(), teleport.WebAPIVersion, opts...)
2406+
require.NoError(t, err)
2407+
clt := client.WebClient{Client: rclt}
2408+
jar.SetCookies(&proxy.webURL, pack.cookies)
2409+
2410+
totpCode, err := totp.GenerateCode(pack.otpSecret, env.clock.Now().Add(30*time.Second))
2411+
require.NoError(t, err)
2412+
2413+
// Obtain a privilege token.
2414+
endpoint := pack.clt.Endpoint("webapi", "users", "privilege", "token")
2415+
re, err := pack.clt.PostJSON(ctx, endpoint, &privilegeTokenRequest{
2416+
SecondFactorToken: totpCode,
2417+
})
2418+
require.NoError(t, err)
2419+
2420+
var privilegeToken string
2421+
require.NoError(t, json.Unmarshal(re.Bytes(), &privilegeToken))
2422+
2423+
names := []string{"x", "??", "%123/", "///", "my/device", "?/%&*1"}
2424+
for _, devName := range names {
2425+
devName := devName
2426+
t.Run(devName, func(t *testing.T) {
2427+
t.Parallel()
2428+
otpSecret := base32.StdEncoding.EncodeToString([]byte(devName))
2429+
dev, err := services.NewTOTPDevice(devName, otpSecret, env.clock.Now())
2430+
require.NoError(t, err)
2431+
err = env.server.Auth().UpsertMFADevice(ctx, pack.user, dev)
2432+
require.NoError(t, err)
2433+
2434+
enc := url.PathEscape(devName)
2435+
_, err = clt.Delete(ctx, pack.clt.Endpoint("webapi", "mfa", "token", privilegeToken, "devices", enc))
2436+
require.NoError(t, err)
2437+
})
2438+
}
2439+
}
2440+
23942441
func TestGetMFADevicesWithAuth(t *testing.T) {
23952442
t.Parallel()
23962443
env := newWebPack(t, 1)

lib/web/app/handler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ func NewHandler(ctx context.Context, c *HandlerConfig) (*Handler, error) {
122122

123123
// Create the application routes.
124124
h.router = httprouter.New()
125+
h.router.UseRawPath = true
125126
h.router.GET("/x-teleport-auth", makeRouterHandler(h.handleFragment))
126127
h.router.POST("/x-teleport-auth", makeRouterHandler(h.handleFragment))
127128
h.router.GET("/teleport-logout", h.withRouterAuth(h.handleLogout))

0 commit comments

Comments
 (0)