소스 검색

csrf: sanitize token after reading from cookie (#6969)

Co-authored-by: Joe Chen <[email protected]>
Toby Simmons 2 년 전
부모
커밋
d54e153fc8
1개의 변경된 파일12개의 추가작업 그리고 2개의 파일을 삭제
  1. 12 2
      internal/context/context.go

+ 12 - 2
internal/context/context.go

@@ -22,6 +22,7 @@ import (
 	"gogs.io/gogs/internal/db"
 	"gogs.io/gogs/internal/errutil"
 	"gogs.io/gogs/internal/form"
+	"gogs.io/gogs/internal/lazyregexp"
 	"gogs.io/gogs/internal/template"
 )
 
@@ -228,6 +229,11 @@ func (c *Context) ServeContent(name string, r io.ReadSeeker, params ...interface
 	http.ServeContent(c.Resp, c.Req.Request, name, modtime, r)
 }
 
+// csrfTokenExcludePattern matches characters that are not used for generating
+// CSRF tokens, see all possible characters at
+// https://github.com/go-macaron/csrf/blob/5d38f39de352972063d1ef026fc477283841bb9b/csrf.go#L148.
+var csrfTokenExcludePattern = lazyregexp.New(`[^a-zA-Z0-9-_].*`)
+
 // Contexter initializes a classic context for a request.
 func Contexter() macaron.Handler {
 	return func(ctx *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) {
@@ -276,8 +282,12 @@ func Contexter() macaron.Handler {
 			}
 		}
 
-		c.Data["CSRFToken"] = x.GetToken()
-		c.Data["CSRFTokenHTML"] = template.Safe(`<input type="hidden" name="_csrf" value="` + x.GetToken() + `">`)
+		// 🚨 SECURITY: Prevent XSS from injected CSRF cookie by stripping all
+		// characters that are not used for generating CSRF tokens, see
+		// https://github.com/gogs/gogs/issues/6953 for details.
+		csrfToken := csrfTokenExcludePattern.ReplaceAllString(x.GetToken(), "")
+		c.Data["CSRFToken"] = csrfToken
+		c.Data["CSRFTokenHTML"] = template.Safe(`<input type="hidden" name="_csrf" value="` + csrfToken + `">`)
 		log.Trace("Session ID: %s", sess.ID())
 		log.Trace("CSRF Token: %v", c.Data["CSRFToken"])