From 006566478a28dba608be3f312f962e0522e9b3ba Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Mon, 27 Apr 2026 07:55:51 +0300 Subject: [PATCH] added explicit gitlab confirmed_at check --- CHANGELOG.md | 4 ++-- tools/auth/gitlab.go | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb35e991..decfd3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,8 @@ - Added dummy bcrypt password check for the failure auth path to minimize enumaration timing attacks when registrations are disabled. -- Adjusted Bitbucket, GitHub and Gitea/Forgejo OAuth2 providers to better reflect recent API updates and doc references. - _The providers also now always send a sepatate emails list request since it has more information about the fetched email than the userinfo endpoint in order to minimize eventual linking security issues caused by custom onpremise setups (e.g. Gitea/Forgejo allows skipping the email verification if an ENV variable is configured)._ +- Adjusted Bitbucket, GitHub, GitLab and Gitea/Forgejo OAuth2 providers to better reflect recent API updates and doc references. + _In case the userinfo data is not sufficient, some of the providers now send a sepatate list emails request in order to minimize eventual linking security issues caused by custom onpremise setups (e.g. Gitea/Forgejo allows skipping the email verification if an ENV variable is configured)._ - ⚠️ Fixed a pre-hijacking OAuth2 linking vulnerability ([#7662](https://github.com/pocketbase/pocketbase/discussions/7662); thanks @Alardiians for reporting it privately). diff --git a/tools/auth/gitlab.go b/tools/auth/gitlab.go index 0fb83b7c..1764d7a4 100644 --- a/tools/auth/gitlab.go +++ b/tools/auth/gitlab.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "strconv" + "time" "github.com/pocketbase/pocketbase/tools/types" "golang.org/x/oauth2" @@ -53,11 +54,12 @@ func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) { } extracted := struct { - Name string `json:"name"` - Username string `json:"username"` - Email string `json:"email"` - AvatarURL string `json:"avatar_url"` - Id int64 `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` + ConfirmedAt string `json:"confirmed_at"` + Id int64 `json:"id"` }{} if err := json.Unmarshal(data, &extracted); err != nil { return nil, err @@ -67,7 +69,6 @@ func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) { Id: strconv.FormatInt(extracted.Id, 10), Name: extracted.Name, Username: extracted.Username, - Email: extracted.Email, AvatarURL: extracted.AvatarURL, RawUser: rawUser, AccessToken: token.AccessToken, @@ -76,5 +77,10 @@ func (p *Gitlab) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) { user.Expiry, _ = types.ParseDateTime(token.Expiry) + confirmedAt, err := time.Parse(time.RFC3339, extracted.ConfirmedAt) + if err == nil && !confirmedAt.IsZero() { + user.Email = extracted.Email + } + return user, nil }