GitLab is a widely used SaaS provider that focuses on developer related issues, including Git repository management, issue tracking and code review. During a recent pen test of GitLab (I wanted to see the service was a good fit to use at Incapsula), I was surprised to come across a vulnerability that leaves users exposed to session hijacking attacks.
While the vulnerability was discovered a while back, we wanted to wait until GitLab had a chance to review and address the issue. They’ve since initiated a series of fixes and approved our disclosure of the vulnerability.
In the following post, I will describe the vulnerability and the steps that GitLab has taken to fix it. I hope that this can be of value to other service providers who might be dealing with similar issues.
First, a bit about session hijacking.
What is Session Hijacking?
Session hijacking is a well-known attack involving the interception of session tokens that identify individual users logged into a website. An attacker can use a hijacked token to access a user’s account, make illegal purchases, change login credentials and access credit card details, just to name a few of the potential consequences.
Methods for stealing session tokens include: man in the middle (MITM) attacks, in which forged authentication keys are used to pass off a connection as secure; brute force attacks, in which a botnet executes millions of requests using random session IDs until an authorized token is found; and SQL injections, in which malicious SQL code is used to access sensitive data.
Uncovering the GitLab Vulnerability
My first indication that there might be an issue with the GitLab service came when I saw that my session token was fully visible in my URL.
Fig. 1: Token is visible in URL.
A simple copy/paste of the token granted me access to every actionable item on the GitLab platform, e.g., user dashboards, account information, individual projects and website code. To make sure this wasn’t a simple glitch, I used the same token on different browsers and machines—all with the same result.
Fig. 2: Token is private, meaning it does not expire.
What’s more, I saw that GitLab authenticates their users with persistent private session tokens. Once issued, they never expire no matter how long a user’s been inactive, or even if they are logged out of their account.
Practically speaking, this means that session tokens are left exposed and vulnerable to any of the attack methods outlined above. Because they do not expire, a stolen token can be used at any time, even months after the theft.
To make matters worse, the tokens were only 20 characters long. As such, they were susceptible to brute force attacks. Given their persistent nature and the admin level access they granted, this added up to a real security concern.
I first contacted GitLab about the vulnerability on May 18th of this year. They informed me that I wasn’t the first to point out the threat—later, I even saw it mentioned on one of their support forums.
Since then, I’ve been in ongoing communication with GitLab regarding their patch plans. By now, they’ve implemented the following measures:
- Replacing private tokens with RSS tokens for fetching RSS feeds to avoid exposing session IDs.
- Expanding personal access tokens that offer role-based access controls. These provide the same functionality as private tokens, albeit with better security.
Additionally, GitLab is gradually phasing out private tokens altogether, a process that is set to be completed in the near future.
Session Hijacking Protection IncapRules
Session hijacking is a serious threat to online users’ privacy, money and identity. Protection comes not only from plugging site vulnerabilities, such as the one discussed above, but also from safeguarding against the attacks, (e.g., MITM, brute force), attempting to exploit them.
Incapsula mitigates these attacks using our proprietary rule engine, IncapRules.
While waiting for GitLab to issue a patch, we created one such rule that protects against brute force attacks by only allowing private tokens on specific types of requests (i.e., atom requests).
This means that an attacker that has obtained a session token will only be able to read, and not add or modify user information.