If your organization uses GitLab for managing your software development lifecycle, you must ensure you’re not misconfiguring the permissions of this open source DevSecOps platform. Doing so can expose your source code, along with sensitive data, while creating security risks. In this blog, we’ll explain how new Tenable plugins can help you keep your GitLab environment secure.
GitLab is one of the most popular source code management (SCM) and continuous integration and delivery/development (CI/CD) open-source solutions. Enterprise developers leverage GitLab to build their organizations’ web applications and automate their deployment. GitLab is available as both a SaaS application and an on-premises solution.
GitLab’s structure is organized into these key components:
GitLab offers administrators the ability to define their access control policy on the different components according to their business needs. This includes:
Use cases for the different types of visibility vary depending on the organization’s business needs. For example, if an organization is hosting an open-source project on a GitLab instance, it would make sense for administrators to set the visibility option for the project or the group to public. On the other hand, an administrator would most likely choose the private or internal options for a GitLab instance dedicated to an internal project.
We recently developed new Tenable Web Application Scanning plugins for GitLab, designed to alert our customers about overpermissive visibility levels. While conducting our research, we identified a number of permission blindspots in GitLab that guided the development of our plugins.
First, we realized that GitLab administrators who want to restrict visibility levels for their groups, projects and snippets can only do so in certain scenarios.
In some cases, administrators can restrict visibility levels only for organization-level groups and for inherited objects. However, they can’t restrict visibility levels for personal namespaces.
According to GitLab’s documentation, the visibility restriction setting “does not apply to groups and projects created under a personal namespace” although there is a feature request to extend this functionality to enterprise users.
GitLab’s documentation provides a workaround for administrators to disable the creation of personal namespaces. However, the workaround’s functionality is limited.
Second, we identified that third-party tools for detecting excessive GitLab permissions rely mainly on the GitLab REST API. But GitLab also offers a GraphQL API, which provides a more flexible and efficient way to query data. Thus, we decided to see if we could use it for our detections.
GitLab instances expose a GraphQL Explorer interface on the https://GITLAB/-/graphql-explorer URL. Although this web interface slightly increases the GitLab attack surface, it doesn’t pose an immediate security risk because its role is mainly to offer a convenient way to send requests to the GitLab GraphQL API. If you’re not an authenticated user of the target GitLab instance, the requests will only allow retrieval of publicly available data.
Let’s look at the type of public data you’re able to access via this method, starting with the following query to retrieve the public groups on a target instance:
Requesting public groups through the GraphQL API
Public groups fetched through the GraphQL API
The response returns all the public groups along with their webUrl, which allows an unauthenticated user to visit those URLs directly.
With the URLs that were returned, an unauthenticated user can now follow the same operation to see the public projects and access their source code:
Requesting public projects through the GraphQL API
Public projects fetched through the GraphQL API
An unauthenticated user also can retrieve information about project topics by specifying the title and description fields in the GraphQL query:
Requesting public topics through the GraphQL API
Public topics fetched through the GraphQL API
We also observed that the code snippets feature can be public depending on the hosting type and the license level, and administrators can’t change the visibility level to private or internal as described in this official issue. The code snippets feature allows users to store pieces of code on the GitLab instance without adding them to a project repository.
That said, we noticed a difference in behaviour between the GitLab REST and GraphQL APIs: using the GraphQL API an unauthenticated user would be able to retrieve the list of public snippets but not with the GitLab REST API.
If you try to use the GitLab REST API to request the list of all public snippets without authentication through the https://GITLAB//api/v4/snippets/public URL, you’ll get a 401 error:
{"message":"401 Unauthorized"}
By trying to access the public snippets through either the https://GITLAB/explore/snippet or https://GITLAB/-/snippets URLs, the unauthenticated user will be redirected to the sign_in page. However, by using the GraphQL API, an unauthenticated user will be able to get the entire list of public snippets and browse its source code:
Requesting public snippets through the GraphQL API
Public snippets fetched through the GraphQL API
Depending on the content of the public code snippet shared by the GitLab users, this could potentially expose sensitive source code to unauthorized users.
Note that unauthenticated users would be able to access GitLab APIs most of the time even in cases where single sign-on (SSO) authentication is enforced, which can help attackers gain access to the exposed data.
Using this method, we found many instances where unauthenticated users would be able to access publicly-available data from GitLab projects. We believe the reason for this is that many GitLab users probably assume incorrectly that the public visibility option restricts viewers to users within their organization. In fact, this option gives visibility to everyone in the world.
In addition, the GitLab platform currently offers administrators a way to set the default visibility for code snippets and enforce access-control over them. However, this feature is not available to all users and depends on customers’ hosting mode and the license level.
This highlights the need for organizations to fully understand the permissions model of the third-party tools they use, and to proactively add controls when possible. To ensure proper implementation of any third-party tool or service, you should carefully review the product documentation to prevent security issues such as data exposure.
Our new plugins for GitLab help customers set up additional controls and monitor the potential misconfigurations discussed above:
Rémy joined Tenable in 2020 as a Senior Research Engineer on the Web Application Scanning Content team. Over the past decade, he led the IT managed services team of a web hosting provider and was responsible for designing and building innovative security services in a Research & Development team. He also contributed to open source security softwares, helping organizations increase their security posture.
Interests outside of work: Rémy enjoys spending time with his family, cooking and traveling the world. Being passionate about offensive security, he enjoys doing ethical hacking in his spare time.