Go

Go

Made by DeepSource

Constant state value in OAuth 2.0 URL GO-S1001

Security
Major
cwe-352 sans top 25

OAuth 2.0 clients must implement CSRF protection for the redirection URI, typically accomplished by including a value that binds the request to the UA's (user-agent) authenticated state. It is recommended to use the "state" request parameter to deliver the value to the authorization server. Go's OAuth 2.0 library allows you to specify a "state" value which is then included in the auth code URL. That state is then provided back by the remote authentication server in the redirect callback, from where it must be validated. If not validated, it makes the client susceptible to a CSRF attack. So it is essential to use a unique, non-guessable "state" value that is also bound to the user's authenticated state with each authentication request and then validated in the redirect callback.

Bad practice

func do(w http.ResponseWriter) {
    const state = "state_value" // harcoded & highly predictable
    conf := &oauth2.Config{
        ClientID:     os.Getenv("CLIENT_ID"),
        ClientSecret: os.Getenv("CLIENT_SECRET"),
        Endpoint: oauth2.Endpoint{
            AuthURL:  "https://*/oauth2/auth",
            TokenURL: "https://*/oauth2/token",
        },
    }

    url := conf.AuthCodeURL(state)
    // ...
}

Recommended

func encodeStateOAuthCookie(w http.ResponseWriter) string {
    b := make([]byte, 256)
    return base64.URLEncoding.EncodeToString(b)
}

func do(w http.ResponseWriter) {
    conf := &oauth2.Config{
        ClientID:     os.Getenv("CLIENT_ID"),
        ClientSecret: os.Getenv("CLIENT_SECRET"),
        Endpoint: oauth2.Endpoint{
            AuthURL:  "https://*/oauth2/auth",
            TokenURL: "https://*/oauth2/token",
        },
    }

    state := encodeStateOAuthCookie(w) // harder to guess
    url := conf.AuthCodeURL(state)
    // ...
}

References