mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
fix: limit OAuth redirects to local paths (#14585)
- This prevents a malicious user from crafting a redirect URL to a nefarious site under their control.
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@ -85,6 +86,15 @@ func ExtractOAuth2(config promoauth.OAuth2Config, client *http.Client, authURLOp
|
||||
|
||||
code := r.URL.Query().Get("code")
|
||||
state := r.URL.Query().Get("state")
|
||||
redirect := r.URL.Query().Get("redirect")
|
||||
if redirect != "" {
|
||||
// We want to ensure that we're only ever redirecting to the application.
|
||||
// We could be more strict here and check to see if the host matches
|
||||
// the host of the AccessURL but ultimately as long as our redirect
|
||||
// url omits a host we're ensuring that we're routing to a path
|
||||
// local to the application.
|
||||
redirect = uriFromURL(redirect)
|
||||
}
|
||||
|
||||
if code == "" {
|
||||
// If the code isn't provided, we'll redirect!
|
||||
@ -119,7 +129,7 @@ func ExtractOAuth2(config promoauth.OAuth2Config, client *http.Client, authURLOp
|
||||
// an old redirect could apply!
|
||||
http.SetCookie(rw, &http.Cookie{
|
||||
Name: codersdk.OAuth2RedirectCookie,
|
||||
Value: r.URL.Query().Get("redirect"),
|
||||
Value: redirect,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
@ -150,7 +160,6 @@ func ExtractOAuth2(config promoauth.OAuth2Config, client *http.Client, authURLOp
|
||||
return
|
||||
}
|
||||
|
||||
var redirect string
|
||||
stateRedirect, err := r.Cookie(codersdk.OAuth2RedirectCookie)
|
||||
if err == nil {
|
||||
redirect = stateRedirect.Value
|
||||
@ -302,3 +311,12 @@ func ExtractOAuth2ProviderAppSecret(db database.Store) func(http.Handler) http.H
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func uriFromURL(u string) string {
|
||||
uri, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return "/"
|
||||
}
|
||||
|
||||
return uri.RequestURI()
|
||||
}
|
||||
|
Reference in New Issue
Block a user