Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Shushlin <v.shushlin@gmail.com>2022-03-21 12:11:47 +0300
committerVladimir Shushlin <v.shushlin@gmail.com>2022-03-28 14:33:26 +0300
commit8c7fe1f00874ea94161570c040136c1b1a53d3a2 (patch)
treea0582cec8c229907e6d8aefae062079f2239be4e /internal/auth/session.go
parente3cb2d50a9af5594c5acb24adabd0f825d0ac75b (diff)
fix: validate that session was issued on the same host
Currently, sessions are valid across all domains. And our auth tokens are also valid for all pages projects user has access to. This means that cookie from one website can be reused on the another. Attackers can steal cookies in many different ways. The easiest way would be to setup a validated custom domain, then proxy all requests to pages server, but log the cookies. Once you have a cookie for attackers domain, you can reuse it on any other pages domain the target user has access to. This commit saves current domain in the session and validates it when reading the session. Changelog: security
Diffstat (limited to 'internal/auth/session.go')
-rw-r--r--internal/auth/session.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/internal/auth/session.go b/internal/auth/session.go
new file mode 100644
index 00000000..40ab6467
--- /dev/null
+++ b/internal/auth/session.go
@@ -0,0 +1,61 @@
+package auth
+
+import (
+ "net/http"
+
+ "github.com/gorilla/sessions"
+
+ "gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/request"
+)
+
+type hostSession struct {
+ *sessions.Session
+}
+
+const sessionHostKey = "_session_host"
+
+func (s *hostSession) Save(r *http.Request, w http.ResponseWriter) error {
+ s.Session.Values[sessionHostKey] = r.Host
+
+ return s.Session.Save(r, w)
+}
+
+func (a *Auth) getSessionFromStore(r *http.Request) (*hostSession, error) {
+ session, err := a.store.Get(r, "gitlab-pages")
+
+ if session != nil {
+ // Cookie just for this domain
+ session.Options.Path = "/"
+ session.Options.HttpOnly = true
+ session.Options.Secure = request.IsHTTPS(r)
+ session.Options.MaxAge = authSessionMaxAge
+
+ if session.Values[sessionHostKey] == nil || session.Values[sessionHostKey] != r.Host {
+ session.Values = make(map[interface{}]interface{})
+ }
+ }
+
+ return &hostSession{session}, err
+}
+
+func (a *Auth) checkSession(w http.ResponseWriter, r *http.Request) (*hostSession, error) {
+ // Create or get session
+ session, errsession := a.getSessionFromStore(r)
+
+ if errsession != nil {
+ // Save cookie again
+ errsave := session.Save(r, w)
+ if errsave != nil {
+ logRequest(r).WithError(errsave).Error(saveSessionErrMsg)
+ captureErrWithReqAndStackTrace(errsave, r)
+ httperrors.Serve500(w)
+ return nil, errsave
+ }
+
+ http.Redirect(w, r, getRequestAddress(r), http.StatusFound)
+ return nil, errsession
+ }
+
+ return session, nil
+}