Skip to content
This repository was archived by the owner on Dec 7, 2020. It is now read-only.

Commit 33c23da

Browse files
author
Bruno Oliveira da Silva
committed
Use HTTP 303 for redirects, instead HTTP 307
Based on the security best practices we should not use HTTP 307 for redirects, instead HTTP 303 should be used. The option `InvalidAuthRedirectsWith303` was removed, as does not make sense to have it anymore. More details: https://tools.ietf.org/id/draft-ietf-oauth-security-topics-08.html#rfc.section.3.9 Resolves #627
1 parent 9fd264c commit 33c23da

File tree

8 files changed

+30
-37
lines changed

8 files changed

+30
-37
lines changed

doc.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,6 @@ type Config struct {
306306
// EncryptionKey is the encryption key used to encrypt the refresh token
307307
EncryptionKey string `json:"encryption-key" yaml:"encryption-key" usage:"encryption key used to encryption the session state" env:"ENCRYPTION_KEY"`
308308

309-
// InvalidAuthRedirectsWith303 will make requests with invalid auth headers redirect using HTTP 303 instead of HTTP 307. See github.com/keycloak/keycloak-gatekeeper/issues/292 for context.
310-
InvalidAuthRedirectsWith303 bool `json:"invalid-auth-redirects-with-303" yaml:"invalid-auth-redirects-with-303" usage:"use HTTP 303 redirects instead of 307 for invalid auth tokens"`
311309
// NoRedirects informs we should hand back a 401 not a redirect
312310
NoRedirects bool `json:"no-redirects" yaml:"no-redirects" usage:"do not have back redirects when no authentication is present, 401 them"`
313311
// SkipTokenVerification tells the service to skipp verifying the access token - for testing purposes

handlers.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (r *oauthProxy) oauthAuthorizationHandler(w http.ResponseWriter, req *http.
101101
return
102102
}
103103

104-
r.redirectToURL(authURL, w, req, http.StatusTemporaryRedirect)
104+
r.redirectToURL(authURL, w, req, http.StatusSeeOther)
105105
}
106106

107107
// getClientAuthMethod maps the config value CLIENT_AUTH_METHOD to valid OAuth2 auth method keys
@@ -229,7 +229,7 @@ func (r *oauthProxy) oauthCallbackHandler(w http.ResponseWriter, req *http.Reque
229229
}
230230
}
231231

232-
r.redirectToURL(redirectURI, w, req, http.StatusTemporaryRedirect)
232+
r.redirectToURL(redirectURI, w, req, http.StatusSeeOther)
233233
}
234234

235235
// loginHandler provide's a generic endpoint for clients to perform a user_credentials login to the provider
@@ -359,7 +359,7 @@ func (r *oauthProxy) logoutHandler(w http.ResponseWriter, req *http.Request) {
359359
}
360360
}
361361

362-
r.redirectToURL(fmt.Sprintf("%s?redirect_uri=%s", sendTo, url.QueryEscape(redirectURL)), w, req, http.StatusTemporaryRedirect)
362+
r.redirectToURL(fmt.Sprintf("%s?redirect_uri=%s", sendTo, url.QueryEscape(redirectURL)), w, req, http.StatusSeeOther)
363363

364364
return
365365
}
@@ -411,7 +411,7 @@ func (r *oauthProxy) logoutHandler(w http.ResponseWriter, req *http.Request) {
411411
}
412412
// step: should we redirect the user
413413
if redirectURL != "" {
414-
r.redirectToURL(redirectURL, w, req, http.StatusTemporaryRedirect)
414+
r.redirectToURL(redirectURL, w, req, http.StatusSeeOther)
415415
}
416416
}
417417

handlers_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func TestLogoutHandlerGood(t *testing.T) {
179179
{
180180
URI: c.WithOAuthURI(logoutURL) + "?redirect=http://example.com",
181181
HasToken: true,
182-
ExpectedCode: http.StatusTemporaryRedirect,
182+
ExpectedCode: http.StatusSeeOther,
183183
ExpectedLocation: "http://example.com",
184184
},
185185
}
@@ -220,7 +220,7 @@ func TestServiceRedirect(t *testing.T) {
220220
{
221221
URI: "/admin",
222222
Redirects: true,
223-
ExpectedCode: http.StatusTemporaryRedirect,
223+
ExpectedCode: http.StatusSeeOther,
224224
ExpectedLocation: "/oauth/authorize?state",
225225
},
226226
{
@@ -248,25 +248,25 @@ func TestAuthorizationURL(t *testing.T) {
248248
URI: "/admin",
249249
Redirects: true,
250250
ExpectedLocation: "/oauth/authorize?state",
251-
ExpectedCode: http.StatusTemporaryRedirect,
251+
ExpectedCode: http.StatusSeeOther,
252252
},
253253
{
254254
URI: "/admin/test",
255255
Redirects: true,
256256
ExpectedLocation: "/oauth/authorize?state",
257-
ExpectedCode: http.StatusTemporaryRedirect,
257+
ExpectedCode: http.StatusSeeOther,
258258
},
259259
{
260260
URI: "/help/../admin",
261261
Redirects: true,
262262
ExpectedLocation: "/oauth/authorize?state",
263-
ExpectedCode: http.StatusTemporaryRedirect,
263+
ExpectedCode: http.StatusSeeOther,
264264
},
265265
{
266266
URI: "/admin?test=yes&test1=test",
267267
Redirects: true,
268268
ExpectedLocation: "/oauth/authorize?state",
269-
ExpectedCode: http.StatusTemporaryRedirect,
269+
ExpectedCode: http.StatusSeeOther,
270270
},
271271
{
272272
URI: "/oauth/test",
@@ -298,19 +298,19 @@ func TestCallbackURL(t *testing.T) {
298298
URI: cfg.WithOAuthURI(callbackURL) + "?code=fake",
299299
ExpectedCookies: map[string]string{cfg.CookieAccessName: ""},
300300
ExpectedLocation: "/",
301-
ExpectedCode: http.StatusTemporaryRedirect,
301+
ExpectedCode: http.StatusSeeOther,
302302
},
303303
{
304304
URI: cfg.WithOAuthURI(callbackURL) + "?code=fake&state=/admin",
305305
ExpectedCookies: map[string]string{cfg.CookieAccessName: ""},
306306
ExpectedLocation: "/",
307-
ExpectedCode: http.StatusTemporaryRedirect,
307+
ExpectedCode: http.StatusSeeOther,
308308
},
309309
{
310310
URI: cfg.WithOAuthURI(callbackURL) + "?code=fake&state=L2FkbWlu",
311311
ExpectedCookies: map[string]string{cfg.CookieAccessName: ""},
312312
ExpectedLocation: "/",
313-
ExpectedCode: http.StatusTemporaryRedirect,
313+
ExpectedCode: http.StatusSeeOther,
314314
},
315315
}
316316
newFakeProxy(cfg).RunTests(t, requests)

middleware_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ func TestOauthRequests(t *testing.T) {
356356
{
357357
URI: "/oauth/authorize",
358358
Redirects: true,
359-
ExpectedCode: http.StatusTemporaryRedirect,
359+
ExpectedCode: http.StatusSeeOther,
360360
},
361361
{
362362
URI: "/oauth/callback",
@@ -379,7 +379,7 @@ func TestOauthRequestsWithBaseURI(t *testing.T) {
379379
{
380380
URI: "/base-uri/oauth/authorize",
381381
Redirects: true,
382-
ExpectedCode: http.StatusTemporaryRedirect,
382+
ExpectedCode: http.StatusSeeOther,
383383
},
384384
{
385385
URI: "/base-uri/oauth/callback",
@@ -614,22 +614,22 @@ func TestNoProxyingRequests(t *testing.T) {
614614
{ // check for escaping
615615
URI: "/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/etc/passwd",
616616
Redirects: true,
617-
ExpectedCode: http.StatusTemporaryRedirect,
617+
ExpectedCode: http.StatusSeeOther,
618618
},
619619
{ // check for escaping
620620
URI: "/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/",
621621
Redirects: true,
622-
ExpectedCode: http.StatusTemporaryRedirect,
622+
ExpectedCode: http.StatusSeeOther,
623623
},
624624
{ // check for escaping
625625
URI: "/../%2e",
626626
Redirects: true,
627-
ExpectedCode: http.StatusTemporaryRedirect,
627+
ExpectedCode: http.StatusSeeOther,
628628
},
629629
{ // check for escaping
630630
URI: "",
631631
Redirects: true,
632-
ExpectedCode: http.StatusTemporaryRedirect,
632+
ExpectedCode: http.StatusSeeOther,
633633
},
634634
}
635635
newFakeProxy(c).RunTests(t, requests)
@@ -650,27 +650,27 @@ func TestStrangeAdminRequests(t *testing.T) {
650650
{ // check for escaping
651651
URI: "//admin%2Ftest",
652652
Redirects: true,
653-
ExpectedCode: http.StatusTemporaryRedirect,
653+
ExpectedCode: http.StatusSeeOther,
654654
},
655655
{ // check for escaping
656656
URI: "///admin/../admin//%2Ftest",
657657
Redirects: true,
658-
ExpectedCode: http.StatusTemporaryRedirect,
658+
ExpectedCode: http.StatusSeeOther,
659659
},
660660
{ // check for escaping
661661
URI: "/admin%2Ftest",
662662
Redirects: true,
663-
ExpectedCode: http.StatusTemporaryRedirect,
663+
ExpectedCode: http.StatusSeeOther,
664664
},
665665
{ // check for prefix slashs
666666
URI: "/" + testAdminURI,
667667
Redirects: true,
668-
ExpectedCode: http.StatusTemporaryRedirect,
668+
ExpectedCode: http.StatusSeeOther,
669669
},
670670
{ // check for double slashs
671671
URI: testAdminURI,
672672
Redirects: true,
673-
ExpectedCode: http.StatusTemporaryRedirect,
673+
ExpectedCode: http.StatusSeeOther,
674674
},
675675
{ // check for double slashs no redirects
676676
URI: "/admin//test",
@@ -681,7 +681,7 @@ func TestStrangeAdminRequests(t *testing.T) {
681681
{ // check for dodgy url
682682
URI: "//admin/.." + testAdminURI,
683683
Redirects: true,
684-
ExpectedCode: http.StatusTemporaryRedirect,
684+
ExpectedCode: http.StatusSeeOther,
685685
},
686686
{ // check for it works
687687
URI: "/" + testAdminURI,
@@ -942,7 +942,7 @@ func TestRolePermissionsMiddleware(t *testing.T) {
942942
{ // check for redirect
943943
URI: "/",
944944
Redirects: true,
945-
ExpectedCode: http.StatusTemporaryRedirect,
945+
ExpectedCode: http.StatusSeeOther,
946946
},
947947
{ // check with a token but not test role
948948
URI: "/",

misc.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,7 @@ func (r *oauthProxy) redirectToAuthorization(w http.ResponseWriter, req *http.Re
107107
w.WriteHeader(http.StatusForbidden)
108108
return r.revokeProxy(w, req)
109109
}
110-
if r.config.InvalidAuthRedirectsWith303 {
111-
r.redirectToURL(r.config.WithOAuthURI(authorizationURL+authQuery), w, req, http.StatusSeeOther)
112-
} else {
113-
r.redirectToURL(r.config.WithOAuthURI(authorizationURL+authQuery), w, req, http.StatusTemporaryRedirect)
114-
}
110+
r.redirectToURL(r.config.WithOAuthURI(authorizationURL+authQuery), w, req, http.StatusSeeOther)
115111

116112
return r.revokeProxy(w, req)
117113
}

misc_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,14 @@ func TestRedirectToAuthorization(t *testing.T) {
3636
URI: "/admin",
3737
Redirects: true,
3838
ExpectedLocation: "/oauth/authorize?state",
39-
ExpectedCode: http.StatusTemporaryRedirect,
39+
ExpectedCode: http.StatusSeeOther,
4040
},
4141
}
4242
newFakeProxy(nil).RunTests(t, requests)
4343
}
4444

4545
func TestRedirectToAuthorizationWith303Enabled(t *testing.T) {
4646
cfg := newFakeKeycloakConfig()
47-
cfg.InvalidAuthRedirectsWith303 = true
4847

4948
requests := []fakeRequest{
5049
{

oauth_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func (r *fakeAuthServer) authHandler(w http.ResponseWriter, req *http.Request) {
188188
}
189189
redirectionURL := fmt.Sprintf("%s?state=%s&code=%s", redirect, state, getRandomString(32))
190190

191-
http.Redirect(w, req, redirectionURL, http.StatusTemporaryRedirect)
191+
http.Redirect(w, req, redirectionURL, http.StatusSeeOther)
192192
}
193193

194194
func (r *fakeAuthServer) logoutHandler(w http.ResponseWriter, req *http.Request) {

server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ func makeTestCodeFlowLogin(location string) (*http.Response, error) {
508508
if err != nil {
509509
return nil, err
510510
}
511-
if resp.StatusCode != http.StatusTemporaryRedirect {
511+
if resp.StatusCode != http.StatusSeeOther {
512512
return nil, errors.New("no redirection found in resp")
513513
}
514514
location = resp.Header.Get("Location")

0 commit comments

Comments
 (0)