Full Report
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 permissions model overviewGitLab’s structure is organized into these key components:Projects: This is the core unit where source code, issues, CI/CD pipelines and other development resources live. Each project contains its own repository and settings. A project can be public, private or internal.Groups: They contain one or more projects to help administrators define high-level organizational units designed for teams or organizations. By leveraging groups, administrators can for, example, automatically assign permissions and apply configurations to their projects. Self-managed GitLab instances and SaaS instances for organizations will automatically provide a top-level group which we will refer to as the “root” or “organization-level” group.User Namespaces: Every GitLab user automatically gets a personal namespace to host personal projects or code snippets to share with other users.GitLab offers administrators the ability to define their access control policy on the different components according to their business needs. This includes:Setting the default visibility for newly created groups, projects or snippets. The three available options are private, internal and public. The public option makes the resource readable to anyone in the world without any authentication.Restricting visibility levels to limit the visibility options available to users when creating or updating resources such as projects, groups or snippets.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.Identifying permissions blindspotsWe 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.Limited visibility controls over personal namespacesFirst, 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.Permission blindspots via GitLab’s GraphQL API: Groups, topics, snippetsSecond, 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.Access to public groupsLet’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 APIThe response returns all the public groups along with their webUrl, which allows an unauthenticated user to visit those URLs directly.Access to public projects and their source codeWith 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 APIAccess to project topicsAn 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 APIAccess to public code snippetsWe 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 APIPublic snippets fetched through the GraphQL APIDepending on the content of the public code snippet shared by the GitLab users, this could potentially expose sensitive source code to unauthorized users.Understand what “public” visibility means on GitLabNote 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.How Tenable Can HelpOur new plugins for GitLab help customers set up additional controls and monitor the potential misconfigurations discussed above: GitLab Public Snippets Detected will check if any public snippet has been detected during the scan when a GitLab instance is detected.GitLab Public Projects Detected will report any public project available when a GitLab instance is detected.
Analysis Summary
# Best Practices: Securing GitLab Permissions and Preventing Data Exposure
## Overview
These practices focus on mitigating the risk of unintended data exposure within GitLab instances due to misconfigurations in project and snippet visibility settings, even when Single Sign-On (SSO) is enforced. The core issue addressed is the common misinterpretation of the "public" visibility setting among users.
## Key Recommendations
### Immediate Actions
1. **Review All Public Visibility Settings:** Immediately audit all existing GitLab projects and code snippets to identify any set to "public" visibility, as this exposes data to the entire internet, regardless of SSO enforcement.
2. **Communicate Visibility Rules:** Disseminate clear, unambiguous documentation to all GitLab users explaining the difference between internal visibility settings and the "public" visibility option (which is global).
3. **Scan for Public Components:** Utilize security scanning tools (like Tenable Web Application Scanning with specific GitLab plugins) to immediately detect and report any existing public projects or snippets.
### Short-term Improvements (1-3 months)
1. **Restrict Default Visibility:** If possible, configure organizational policies to restrict the default visibility setting for new projects and code snippets to "internal" or "private," overriding any potentially lax defaults provided by the license level.
2. **Implement Access Control Over Snippets:** If the hosting mode and license permit, enable and enforce access controls specifically for code snippets, as this feature may not be universally available or active by default.
3. **Establish Permission Verification Workflow:** Integrate pre-deployment configuration checks into CI/CD pipelines (or administrative checklists) to flag any proposed change that sets a project or snippet to public visibility.
### Long-term Strategy (3+ months)
1. **Comprehensive Permissions Model Understanding:** Develop and maintain detailed documentation outlining the exact permissions model for the specific GitLab deployment (hosting mode/license level) to identify any feature gaps or limitations in access control enforcement.
2. **External Validation Mechanism:** Implement continuous monitoring using vulnerability management or exposure management platforms to regularly scan the GitLab instance for publicly exposed assets, providing an independent verification against user error.
3. **User Training Reinforcement:** Schedule recurring mandatory training sessions focused specifically on data classification, access control implications, and the scope of GitLab's visibility settings.
## Implementation Guidance
### For Small Organizations
- **Start with Inventory:** Conduct a manual or automated inventory of all projects and snippets. If the volume is low, prioritize manual verification of every asset marked as "public."
- **Leverage Native Controls:** Ensure SSO, if used, is correctly bound and enforced, but *do not* rely on it as the sole defense against public exposure. Configure the strictest practical visibility defaults in the administrative settings.
### For Medium Organizations
- **Integrate Scanning Agents:** Deploy Tenable Web Application Scanning (or similar tools) configured with specific plugins designed to query and report on public project/snippet detection for regular scanning schedules.
- **Document Exceptions:** Create a formal, documented process for requiring justifiable approval (by security/management) whenever a project *must* be set to public visibility.
### For Large Enterprises
- **Automate Enforcement via Infrastructure as Code (IaC):** If using GitOps or configuration management for GitLab, enforce visibility settings via IaC templates to prevent undocumented manual overrides in the UI.
- **Centralized Exposure Management:** Integrate GitLab configuration auditing into a broader Exposure Management Platform to correlate public exposure findings with overall organizational risk scoring and attack path analysis.
- **License Review:** Review the current GitLab license level to confirm which access-control features (especially for snippets) are available and enforce their activation where possible.
## Configuration Examples
| Component | Recommended Configuration/Action | Corresponding Tenable Plugin Check |
| :--- | :--- | :--- |
| **Project Visibility** | Set default visibility to **Internal** or **Private**. | `GitLab Public Projects Detected` (Plugin ID 114617) |
| **Snippet Visibility** | Restrict visibility options based on license capabilities; enforce non-public defaults. | `GitLab Public Snippets Detected` (Plugin ID 114619) |
| **Authentication** | Ensure SSO is enforced, but explicitly communicate that SSO **does not** override public internet visibility. | N/A (Relies on correct user understanding) |
## Compliance Alignment
- **NIST CSF (Identify/Protect):** Focuses on understanding assets, governance, and access control management.
- **ISO 27001 (A.9 Access Control):** Directly addresses controlling access based on business/security requirements.
- **CIS Benchmarks for GitLab:** Following configuration standards will naturally lead to stricter permission settings.
## Common Pitfalls to Avoid
1. **Assuming SSO Covers Everything:** Believing that enabling SSO automatically restricts access to the internal network; public visibility overrides SSO for global access.
2. **Ignoring Snippets:** Focusing security efforts solely on projects while neglecting code snippets, which can also be exposed publicly.
3. **Relying on User Assumption:** Assuming users understand the nuances of "public" visibility versus internal organizational sharing. Always enforce security through configuration, not just training.
4. **Failing to Review Documentation:** Not thoroughly reviewing GitLab product documentation regarding feature availability based on license level, which leads to missing layers of security control enforcement.
## Resources
- **Tenable GitLab Plugins:** Utilize the specific plugins (e.g., 114617, 114619) available via Tenable's Web Application Scanning/Security Center for automated detection of public assets.
- **GitLab Documentation:** Consult official documentation for the specific hosted version (Self-Managed vs. SaaS) and license tier to understand available administrative controls and default configurations.
- **Tenable One Exposure Management Platform:** Use solutions like Tenable One for aggregated visibility, continuous configuration auditing, and attack path prioritization related to exposed assets.