Skip to content

Reset Session ID on login (#18018) #18041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8
gitea.com/lunny/levelqueue v0.4.1
github.com/Microsoft/go-winio v0.5.0 // indirect
github.com/NYTimes/gziphandler v1.1.1
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e h1:zgPGaf3kXP0cVm9J0l8
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0=
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e h1:YjaQU6XFicdhPN+MlGolcXO8seYY2+EY5g7vZPB17CQ=
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e/go.mod h1:nfA7JaGv3hbGQ1ktdhAsZhdS84qKffI8NMlHr+Opsog=
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee h1:9U6HuKUBt/cGK6T/64dEuz0r7Yp97WAAEJvXHDlY3ws=
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee/go.mod h1:Ozg8IchVNb/Udg+ui39iHRYqVHSvf3C99ixdpLR8Vu0=
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8 h1:tJQRXgZigkLeeW9LPlps9G9aMoE6LAmqigLA+wxmd1Q=
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8/go.mod h1:fc/pjt5EqNKgqQXYzcas1Z5L5whkZHyOvTA7OzWVJck=
gitea.com/lunny/levelqueue v0.4.1 h1:RZ+AFx5gBsZuyqCvofhAkPQ9uaVDPJnsULoJZIYaJNw=
gitea.com/lunny/levelqueue v0.4.1/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
Expand Down Expand Up @@ -325,8 +325,9 @@ github.com/go-asn1-ber/asn1-ber v1.5.3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro
github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k=
github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg=
github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.4 h1:5e494iHzsYBiyXQAHHuI4tyJS9M3V84OuX3ufIIGHFo=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-enry/go-enry/v2 v2.7.1 h1:WCqtfyteIz61GYk9lRVy8HblvIv4cP9GIiwm/6txCbU=
Expand Down
12 changes: 12 additions & 0 deletions modules/session/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,21 @@

package session

import (
"net/http"

"gitea.com/go-chi/session"
)

// Store represents a session store
type Store interface {
Get(interface{}) interface{}
Set(interface{}, interface{}) error
Delete(interface{}) error
}

// RegenerateSession regenerates the underlying session and returns the new store
func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, error) {
s, err := session.RegenerateSession(resp, req)
return s, err
}
66 changes: 61 additions & 5 deletions routers/web/user/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/web"
Expand Down Expand Up @@ -87,6 +88,10 @@ func AutoSignIn(ctx *context.Context) (bool, error) {

isSucceed = true

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
return false, fmt.Errorf("unable to RegenerateSession: Error: %w", err)
}

// Set session IDs
if err := ctx.Session.Set("uid", u.ID); err != nil {
return false, err
Expand Down Expand Up @@ -235,6 +240,11 @@ func SignInPost(ctx *context.Context) {
return
}

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("UserSignIn: Unable to set regenerate session", err)
return
}

// User needs to use 2FA, save data and redirect to 2FA page.
if err := ctx.Session.Set("twofaUid", u.ID); err != nil {
ctx.ServerError("UserSignIn: Unable to set twofaUid in session", err)
Expand Down Expand Up @@ -395,6 +405,9 @@ func TwoFactorScratchPost(ctx *context.Context) {
}

handleSignInFull(ctx, u, remember, false)
if ctx.Written() {
return
}
ctx.Flash.Info(ctx.Tr("auth.twofa_scratch_used"))
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
return
Expand Down Expand Up @@ -505,6 +518,9 @@ func U2FSign(ctx *context.Context) {
}
}
redirect := handleSignInFull(ctx, user, remember, false)
if ctx.Written() {
return
}
if redirect == "" {
redirect = setting.AppSubURL + "/"
}
Expand All @@ -517,7 +533,11 @@ func U2FSign(ctx *context.Context) {

// This handles the final part of the sign-in process of the user.
func handleSignIn(ctx *context.Context, u *models.User, remember bool) {
handleSignInFull(ctx, u, remember, true)
redirect := handleSignInFull(ctx, u, remember, true)
if ctx.Written() {
return
}
ctx.Redirect(redirect)
}

func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyRedirect bool) string {
Expand All @@ -528,6 +548,12 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
setting.CookieRememberName, u.Name, days)
}

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("RegenerateSession", err)
return setting.AppSubURL + "/"
}

// Delete the openid, 2fa and linkaccount data
_ = ctx.Session.Delete("openid_verified_uri")
_ = ctx.Session.Delete("openid_signin_remember")
_ = ctx.Session.Delete("openid_determined_email")
Expand All @@ -551,7 +577,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
if len(u.Language) == 0 {
u.Language = ctx.Locale.Language()
if err := models.UpdateUserCols(u, "language"); err != nil {
log.Error(fmt.Sprintf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language))
ctx.ServerError("UpdateUserCols Language", fmt.Errorf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language))
return setting.AppSubURL + "/"
}
}
Expand Down Expand Up @@ -697,6 +723,11 @@ func getUserName(gothUser *goth.User) string {
}

func showLinkingLogin(ctx *context.Context, gothUser goth.User) {
if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("RegenerateSession", err)
return
}

if err := ctx.Session.Set("linkAccountGothUser", gothUser); err != nil {
log.Error("Error setting linkAccountGothUser in session: %v", err)
}
Expand Down Expand Up @@ -736,6 +767,11 @@ func handleOAuth2SignIn(ctx *context.Context, u *models.User, gothUser goth.User
return
}

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("RegenerateSession", err)
return
}

if err := ctx.Session.Set("uid", u.ID); err != nil {
log.Error("Error setting uid in session: %v", err)
}
Expand Down Expand Up @@ -776,6 +812,11 @@ func handleOAuth2SignIn(ctx *context.Context, u *models.User, gothUser goth.User
return
}

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("RegenerateSession", err)
return
}

// User needs to use 2FA, save data and redirect to 2FA page.
if err := ctx.Session.Set("twofaUid", u.ID); err != nil {
log.Error("Error setting twofaUid in session: %v", err)
Expand Down Expand Up @@ -965,6 +1006,11 @@ func linkAccount(ctx *context.Context, u *models.User, gothUser goth.User, remem
return
}

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("RegenerateSession", err)
return
}

// User needs to use 2FA, save data and redirect to 2FA page.
if err := ctx.Session.Set("twofaUid", u.ID); err != nil {
log.Error("Error setting twofaUid in session: %v", err)
Expand Down Expand Up @@ -1102,7 +1148,7 @@ func LinkAccountPostRegister(ctx *context.Context) {
return
}

ctx.Redirect(setting.AppSubURL + "/user/login")
handleSignIn(ctx, u, false)
}

// HandleSignOut resets the session and sets the cookies
Expand Down Expand Up @@ -1244,7 +1290,7 @@ func SignUpPost(ctx *context.Context) {
}

ctx.Flash.Success(ctx.Tr("auth.sign_up_successful"))
handleSignInFull(ctx, u, false, true)
handleSignIn(ctx, u, false)
}

// createAndHandleCreatedUser calls createUserInContext and
Expand Down Expand Up @@ -1465,6 +1511,13 @@ func handleAccountActivation(ctx *context.Context, user *models.User) {

log.Trace("User activated: %s", user.Name)

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
log.Error("Unable to regenerate session for user: %-v with email: %s: %v", user, user.Email, err)
ctx.ServerError("ActivateUserEmail", err)
return
}

// Set session IDs
if err := ctx.Session.Set("uid", user.ID); err != nil {
log.Error("Error setting uid in session[%s]: %v", ctx.Session.ID(), err)
}
Expand Down Expand Up @@ -1737,11 +1790,14 @@ func ResetPasswdPost(ctx *context.Context) {

handleSignInFull(ctx, u, remember, false)
ctx.Flash.Info(ctx.Tr("auth.twofa_scratch_used"))
if ctx.Written() {
return
}
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
return
}

handleSignInFull(ctx, u, remember, true)
handleSignIn(ctx, u, remember)
}

// MustChangePassword renders the page to change a user's password
Expand Down
6 changes: 6 additions & 0 deletions routers/web/user/auth_openid.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/hcaptcha"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
Expand Down Expand Up @@ -231,6 +232,11 @@ func signInOpenIDVerify(ctx *context.Context) {
}
}

if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil {
ctx.ServerError("RegenerateSession", err)
return
}

if err := ctx.Session.Set("openid_verified_uri", id); err != nil {
log.Error("signInOpenIDVerify: Could not set openid_verified_uri in session: %v", err)
}
Expand Down
11 changes: 10 additions & 1 deletion services/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/web/middleware"
)
Expand Down Expand Up @@ -95,6 +96,14 @@ func isGitRawReleaseOrLFSPath(req *http.Request) bool {

// handleSignIn clears existing session variables and stores new ones for the specified user object
func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore, user *models.User) {
// We need to regenerate the session...
newSess, err := session.RegenerateSession(resp, req)
if err != nil {
log.Error(fmt.Sprintf("Error regenerating session: %v", err))
} else {
sess = newSess
}

_ = sess.Delete("openid_verified_uri")
_ = sess.Delete("openid_signin_remember")
_ = sess.Delete("openid_determined_email")
Expand All @@ -103,7 +112,7 @@ func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore
_ = sess.Delete("twofaRemember")
_ = sess.Delete("u2fChallenge")
_ = sess.Delete("linkAccount")
err := sess.Set("uid", user.ID)
err = sess.Set("uid", user.ID)
if err != nil {
log.Error(fmt.Sprintf("Error setting session: %v", err))
}
Expand Down
6 changes: 3 additions & 3 deletions vendor/gitea.com/go-chi/session/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/gitea.com/go-chi/session/go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 2 additions & 10 deletions vendor/gitea.com/go-chi/session/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading