api: fix critical CSRF vulnerabilities on API routes (#5355)

By explicitly requires token authentication.
This commit is contained in:
Unknwon 2018-11-28 21:05:58 -05:00
parent e9be8016e6
commit 3db9b06a6e
No known key found for this signature in database
GPG Key ID: 25B575AE3213B2B3
5 changed files with 34 additions and 32 deletions

View File

@ -16,7 +16,7 @@ import (
"github.com/gogs/gogs/pkg/setting" "github.com/gogs/gogs/pkg/setting"
) )
const APP_VER = "0.11.70.1126" const APP_VER = "0.11.71.1128"
func init() { func init() {
setting.AppVer = APP_VER setting.AppVer = APP_VER

View File

@ -23,10 +23,11 @@ func IsAPIPath(url string) bool {
return strings.HasPrefix(url, "/api/") return strings.HasPrefix(url, "/api/")
} }
// SignedInID returns the id of signed in user. // SignedInID returns the id of signed in user, along with one bool value which indicates whether user uses token
func SignedInID(c *macaron.Context, sess session.Store) int64 { // authentication.
func SignedInID(c *macaron.Context, sess session.Store) (_ int64, isTokenAuth bool) {
if !models.HasEngine { if !models.HasEngine {
return 0 return 0, false
} }
// Check access token. // Check access token.
@ -53,40 +54,40 @@ func SignedInID(c *macaron.Context, sess session.Store) int64 {
if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) { if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) {
log.Error(2, "GetAccessTokenBySHA: %v", err) log.Error(2, "GetAccessTokenBySHA: %v", err)
} }
return 0 return 0, false
} }
t.Updated = time.Now() t.Updated = time.Now()
if err = models.UpdateAccessToken(t); err != nil { if err = models.UpdateAccessToken(t); err != nil {
log.Error(2, "UpdateAccessToken: %v", err) log.Error(2, "UpdateAccessToken: %v", err)
} }
return t.UID return t.UID, true
} }
} }
uid := sess.Get("uid") uid := sess.Get("uid")
if uid == nil { if uid == nil {
return 0 return 0, false
} }
if id, ok := uid.(int64); ok { if id, ok := uid.(int64); ok {
if _, err := models.GetUserByID(id); err != nil { if _, err := models.GetUserByID(id); err != nil {
if !errors.IsUserNotExist(err) { if !errors.IsUserNotExist(err) {
log.Error(2, "GetUserByID: %v", err) log.Error(2, "GetUserByID: %v", err)
} }
return 0 return 0, false
} }
return id return id, false
} }
return 0 return 0, false
} }
// SignedInUser returns the user object of signed user. // SignedInUser returns the user object of signed in user, along with two bool values,
// It returns a bool value to indicate whether user uses basic auth or not. // which indicate whether user uses HTTP Basic Authentication or token authentication respectively.
func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool) { func SignedInUser(ctx *macaron.Context, sess session.Store) (_ *models.User, isBasicAuth bool, isTokenAuth bool) {
if !models.HasEngine { if !models.HasEngine {
return nil, false return nil, false, false
} }
uid := SignedInID(ctx, sess) uid, isTokenAuth := SignedInID(ctx, sess)
if uid <= 0 { if uid <= 0 {
if setting.Service.EnableReverseProxyAuth { if setting.Service.EnableReverseProxyAuth {
@ -95,8 +96,8 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
u, err := models.GetUserByName(webAuthUser) u, err := models.GetUserByName(webAuthUser)
if err != nil { if err != nil {
if !errors.IsUserNotExist(err) { if !errors.IsUserNotExist(err) {
log.Error(4, "GetUserByName: %v", err) log.Error(2, "GetUserByName: %v", err)
return nil, false return nil, false, false
} }
// Check if enabled auto-registration. // Check if enabled auto-registration.
@ -109,14 +110,14 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
} }
if err = models.CreateUser(u); err != nil { if err = models.CreateUser(u); err != nil {
// FIXME: should I create a system notice? // FIXME: should I create a system notice?
log.Error(4, "CreateUser: %v", err) log.Error(2, "CreateUser: %v", err)
return nil, false return nil, false, false
} else { } else {
return u, false return u, false, false
} }
} }
} }
return u, false return u, false, false
} }
} }
@ -130,21 +131,21 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
u, err := models.UserLogin(uname, passwd, -1) u, err := models.UserLogin(uname, passwd, -1)
if err != nil { if err != nil {
if !errors.IsUserNotExist(err) { if !errors.IsUserNotExist(err) {
log.Error(4, "UserLogin: %v", err) log.Error(2, "UserLogin: %v", err)
} }
return nil, false return nil, false, false
} }
return u, true return u, true, false
} }
} }
return nil, false return nil, false, false
} }
u, err := models.GetUserByID(uid) u, err := models.GetUserByID(uid)
if err != nil { if err != nil {
log.Error(4, "GetUserById: %v", err) log.Error(2, "GetUserByID: %v", err)
return nil, false return nil, false, false
} }
return u, false return u, false, isTokenAuth
} }

View File

@ -40,6 +40,7 @@ type Context struct {
User *models.User User *models.User
IsLogged bool IsLogged bool
IsBasicAuth bool IsBasicAuth bool
IsTokenAuth bool
Repo *Repository Repo *Repository
Org *Organization Org *Organization
@ -289,8 +290,8 @@ func Contexter() macaron.Handler {
c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With") c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
} }
// Get user from session if logined. // Get user from session or header when possible
c.User, c.IsBasicAuth = auth.SignedInUser(c.Context, c.Session) c.User, c.IsBasicAuth, c.IsTokenAuth = auth.SignedInUser(c.Context, c.Session)
if c.User != nil { if c.User != nil {
c.IsLogged = true c.IsLogged = true

View File

@ -86,7 +86,7 @@ func repoAssignment() macaron.Handler {
// Contexter middleware already checks token for user sign in process. // Contexter middleware already checks token for user sign in process.
func reqToken() macaron.Handler { func reqToken() macaron.Handler {
return func(c *context.Context) { return func(c *context.Context) {
if !c.IsLogged { if !c.IsTokenAuth {
c.Error(401) c.Error(401)
return return
} }

View File

@ -1 +1 @@
0.11.70.1126 0.11.71.1128