VYPR
Unrated severityNVD Advisory· Published Dec 13, 2021· Updated Aug 4, 2024

CVE-2021-39937

CVE-2021-39937

Description

A collision in access memoization logic in all versions of GitLab CE/EE before 14.3.6, all versions starting from 14.4 before 14.4.4, all versions starting from 14.5 before 14.5.2, leads to potential elevated privileges in groups and projects under rare circumstances

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A collision in GitLab's access memoization logic can cause incorrect privilege elevation for groups and projects when IDs collide.

Vulnerability

The BulkMemberAccessLoad concern in GitLab CE/EE (all versions before 14.3.6, 14.4.0-14.4.3, 14.5.0-14.5.1) uses a memoization key "max_member_access_for_#{klass.name.underscore.pluralize}:#{memoization_index}" that does not differentiate between project and group IDs. When a project and a group share the same numeric ID, the cached access level for one can be incorrectly returned for the other within the same request [1].

Exploitation

An attacker would need to be able to trigger a request that queries both a group and a project with the same ID. This could occur via GraphQL multiplexing or other API endpoints that evaluate access for multiple resources. The attacker must have some level of access to one of the resources (e.g., maintainer on a group) to cause the memoization of that access level, which then incorrectly applies to the other resource (e.g., a project with the same ID) if the attacker has no or lower access there [1].

Impact

Successful exploitation could lead to elevated privileges, allowing an attacker to gain unauthorized access to groups or projects. The impact is limited to scenarios where ID collisions occur and the attacker has some access to one resource. The vulnerability could result in information disclosure or unauthorized actions depending on the privileges gained [1].

Mitigation

GitLab released fixes in versions 14.3.6, 14.4.4, and 14.5.2. Users should upgrade to these or later versions. No workaround is available. The fix differentiates memoization keys by model type [1].

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

3

Patches

0

No patches discovered yet.

Vulnerability mechanics

Root cause

"The memoization key in BulkMemberAccessLoad does not differentiate between project and group IDs, causing cache collisions that return stale access levels."

Attack vector

An attacker can exploit a collision in the memoization cache used by `BulkMemberAccessLoad` [ref_id=1]. If a group with ID=6 grants the attacker `MAINTAINER` access, that result is cached under the key `max_member_access_for_users:6` [ref_id=1]. On the same request, if the attacker then queries a project with ID=6 to which they have no access, the cached value `MAINTAINER` is returned without a database lookup, granting elevated privileges [ref_id=1]. The reverse scenario also applies: a cached "no access" result for a project can incorrectly deny access to a group sharing the same ID [ref_id=1]. The advisory notes this is likely exploitable via the GraphQL API using multiplexed queries [ref_id=1].

Affected code

The vulnerability resides in the `BulkMemberAccessLoad` concern, specifically in the memoization key construction at [this line](https://gitlab.com/gitlab-org/gitlab/-/blob/64ada62a60172dff2c70a2c9636492651e8e7d1c/app/models/concerns/bulk_member_access_load.rb#L45) [ref_id=1]. The key is built as `"max_member_access_for_#{klass.name.underscore.pluralize}:#{memoization_index}"`, but `memoization_index` does not differentiate whether the stored ID belongs to a project or a group [ref_id=1].

What the fix does

The advisory recommends changing the memoization key on [this line](https://gitlab.com/gitlab-org/gitlab/-/blob/64ada62a60172dff2c70a2c9636492651e8e7d1c/app/models/concerns/bulk_member_access_load.rb#L45) to include the model type as part of the key, so that a project ID and a group ID with the same numeric value are stored under distinct cache entries [ref_id=1]. No patch diff is provided in the bundle, but the suggested fix would prevent the collision by ensuring the cache key differentiates between models [ref_id=1].

Preconditions

  • inputThe attacker must be able to send a single request (e.g., a multiplexed GraphQL query) that triggers access checks for both a group and a project that share the same numeric ID.
  • authThe attacker must have at least some level of access to one of the colliding resources (group or project) to seed the memoization cache with a privilege level.

Generated on May 25, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.