Incorrect authorization in OAuth2-Proxy
Description
OAuth2-Proxy is an open source reverse proxy that provides authentication with Google, Github or other providers. The --gitlab-group flag for group-based authorization in the GitLab provider stopped working in the v7.0.0 release. Regardless of the flag settings, authorization wasn't restricted. Additionally, any authenticated users had whichever groups were set in --gitlab-group added to the new X-Forwarded-Groups header to the upstream application. While adding GitLab project based authorization support in #630, a bug was introduced where the user session's groups field was populated with the --gitlab-group config entries instead of pulling the individual user's group membership from the GitLab Userinfo endpoint. When the session groups where compared against the allowed groups for authorization, they matched improperly (since both lists were populated with the same data) so authorization was allowed. This impacts GitLab Provider users who relies on group membership for authorization restrictions. Any authenticated users in your GitLab environment can access your applications regardless of --gitlab-group membership restrictions. This is patched in v7.1.0. There is no workaround for the Group membership bug. But --gitlab-project can be set to use Project membership as the authorization checks instead of groups; it is not broken.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
OAuth2-Proxy v7.0.0 GitLab group authorization check is broken, allowing any authenticated user access regardless of --gitlab-group settings.
Vulnerability
Overview
In OAuth2-Proxy version 7.0.0, the --gitlab-group flag for group-based authorization with the GitLab provider stopped functioning correctly. Due to a bug introduced when adding GitLab project-based authorization support (pull request #630), the user session's groups field was incorrectly populated with the static --gitlab-group configuration entries instead of fetching the individual user's actual group membership from the GitLab Userinfo endpoint [2]. As a result, the authorization check compared two identical lists (both containing the configured groups) and always passed, allowing any authenticated user access to upstream applications regardless of their actual group membership [1][2].
Exploitation
An attacker who has authenticated to any GitLab instance integrated with the vulnerable OAuth2-Proxy can bypass group-based authorization restrictions. No special network position or further authentication is required beyond a valid GitLab user session. The bug affects all deployments using the GitLab provider with --gitlab-group for access control. Additionally, the configured group names are forwarded in the X-Forwarded-Groups header to upstream applications, potentially leaking internal group structure information [2].
Impact
Any authenticated user in the GitLab environment can access protected upstream applications that should have been restricted to specific GitLab groups. The authorization mechanism is completely bypassed, making --gitlab-group ineffective for access control. Upstream applications may receive group headers that do not reflect the user's actual membership, which could lead to additional privilege escalation if those applications rely on the forwarded groups [1][2].
Mitigation
The vulnerability is fixed in OAuth2-Proxy v7.1.0. There is no workaround for the group membership bug; however, administrators can use the --gitlab-project flag as an alternative authorization method based on project membership, which is not affected [2]. Users are strongly advised to upgrade to the patched version immediately.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/oauth2-proxy/oauth2-proxy/v7Go | < 7.1.0 | 7.1.0 |
Affected products
6- osv-coords5 versionspkg:bitnami/oauth2-proxypkg:golang/github.com/oauth2-proxy/oauth2-proxy/v7pkg:rpm/opensuse/govulncheck-vulndb&distro=openSUSE%20Leap%2015.6pkg:rpm/opensuse/govulncheck-vulndb&distro=openSUSE%20Tumbleweedpkg:rpm/suse/govulncheck-vulndb&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Package%20Hub%2015%20SP6
>= 7.0.0, < 7.1.0+ 4 more
- (no CPE)range: >= 7.0.0, < 7.1.0
- (no CPE)range: < 7.1.0
- (no CPE)range: < 0.0.20250814T182633-150000.1.98.1
- (no CPE)range: < 0.0.20250811T192933-1.1
- (no CPE)range: < 0.0.20250814T182633-150000.1.98.1
- oauth2-proxy/oauth2-proxyv5Range: >= 7.0.0, < 7.1.0
Patches
10279fa7dff17Merge pull request from GHSA-652x-m2gr-hppm
2 files changed · +13 −25
providers/gitlab.go+5 −17 modified@@ -295,21 +295,13 @@ func (p *GitLabProvider) EnrichSession(ctx context.Context, s *sessions.SessionS s.User = userInfo.Username s.Email = userInfo.Email - - p.addGroupsToSession(ctx, s) + for _, group := range userInfo.Groups { + s.Groups = append(s.Groups, fmt.Sprintf("group:%s", group)) + } p.addProjectsToSession(ctx, s) return nil - -} - -// addGroupsToSession projects into session.Groups -func (p *GitLabProvider) addGroupsToSession(ctx context.Context, s *sessions.SessionState) { - // Iterate over projects, check if oauth2-proxy can get project information on behalf of the user - for _, group := range p.Groups { - s.Groups = append(s.Groups, fmt.Sprintf("group:%s", group)) - } } // addProjectsToSession adds projects matching user access requirements into the session state groups list @@ -341,24 +333,20 @@ func (p *GitLabProvider) addProjectsToSession(ctx context.Context, s *sessions.S } else { logger.Errorf("Warning: user %q does not have the minimum required access level for project %q", s.Email, project.Name) } - } else { - logger.Errorf("Warning: project %s is archived", project.Name) + continue } + logger.Errorf("Warning: project %s is archived", project.Name) } - } // PrefixAllowedGroups returns a list of allowed groups, prefixed by their `kind` value func (p *GitLabProvider) PrefixAllowedGroups() (groups []string) { - for _, val := range p.Groups { groups = append(groups, fmt.Sprintf("group:%s", val)) } - for _, val := range p.Projects { groups = append(groups, fmt.Sprintf("project:%s", val.Name)) } - return groups }
providers/gitlab_test.go+8 −8 modified@@ -232,40 +232,40 @@ var _ = Describe("Gitlab Provider Tests", func() { Expect(session.Groups).To(Equal(in.expectedValue)) }, Entry("project membership valid on group project", entitiesTableInput{ - expectedValue: []string{"project:my_group/my_project"}, + expectedValue: []string{"group:foo", "group:bar", "project:my_group/my_project"}, projects: []string{"my_group/my_project"}, }), Entry("project membership invalid on group project, insufficient access level level", entitiesTableInput{ - expectedValue: nil, + expectedValue: []string{"group:foo", "group:bar"}, projects: []string{"my_group/my_project=40"}, }), Entry("project membership invalid on group project, no access at all", entitiesTableInput{ expectedValue: nil, projects: []string{"no_access_group/no_access_project=30"}, }), Entry("project membership valid on personnal project", entitiesTableInput{ - expectedValue: []string{"project:my_profile/my_personal_project"}, + expectedValue: []string{"group:foo", "group:bar", "project:my_profile/my_personal_project"}, projects: []string{"my_profile/my_personal_project"}, }), Entry("project membership invalid on personnal project, insufficient access level", entitiesTableInput{ - expectedValue: nil, + expectedValue: []string{"group:foo", "group:bar"}, projects: []string{"my_profile/my_personal_project=40"}, }), Entry("project membership invalid", entitiesTableInput{ - expectedValue: nil, + expectedValue: []string{"group:foo", "group:bar"}, projects: []string{"my_group/my_bad_project"}, }), Entry("group membership valid", entitiesTableInput{ - expectedValue: []string{"group:foo"}, + expectedValue: []string{"group:foo", "group:bar"}, groups: []string{"foo"}, }), Entry("groups and projects", entitiesTableInput{ - expectedValue: []string{"group:foo", "group:baz", "project:my_group/my_project", "project:my_profile/my_personal_project"}, + expectedValue: []string{"group:foo", "group:bar", "project:my_group/my_project", "project:my_profile/my_personal_project"}, groups: []string{"foo", "baz"}, projects: []string{"my_group/my_project", "my_profile/my_personal_project"}, }), Entry("archived projects", entitiesTableInput{ - expectedValue: nil, + expectedValue: []string{"group:foo", "group:bar"}, groups: []string{}, projects: []string{"my_group/my_archived_project"}, }),
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-652x-m2gr-hppmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21411ghsaADVISORY
- docs.gitlab.com/ee/user/groupghsaWEB
- docs.gitlab.com/ee/user/group/mitrex_refsource_MISC
- github.com/oauth2-proxy/oauth2-proxy/commit/0279fa7dff1752f1710707dbd1ffac839de8bbfcghsax_refsource_MISCWEB
- github.com/oauth2-proxy/oauth2-proxy/releases/tag/v7.1.0ghsax_refsource_MISCWEB
- github.com/oauth2-proxy/oauth2-proxy/security/advisories/GHSA-652x-m2gr-hppmghsax_refsource_CONFIRMWEB
- pkg.go.dev/github.com/oauth2-proxy/oauth2-proxy/v7ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.