IDOR in securityPolicyProjectAssign Mutation Allows Guest User to Read Security Policy YAML
HackerOne report #2818270 by yuki_osaki
on 2024-11-03, assigned to @kmorrison1:
Report | Attachments | How To Reproduce
Report
Summary
The securityPolicyProjectAssign mutation does not properly authorize the securityPolicyProjectId parameter, bypassing the intended fix of CVE-2023-4002 (https://about.gitlab.com/releases/2023/08/01/security-release-gitlab-16-2-2-released/) and reintroducing the vulnerability. Although CVE-2023-4002 originally added authorization checks to prevent unauthorized access, this check is insufficient, resulting in incomplete access restriction.
In private project, guest users are restricted from reading code which mean that cannot read the contents of security policies. However, by directly calling the securityPolicyProjectAssign mutation, a guest user can access the YAML content of the security policy. This leads to an IDOR , allowing unauthorized users to view sensitive policy data.
Details of the Bypass
The patch for CVE-2023-4002 introduced the following authorization check:
080914bd
ee/app/graphql/mutations/security_policy/assign_security_policy_project.rb
def can_access_security_policy?(policy_project)
Ability.allowed?(current_user, :read_security_orchestration_policy_project, policy_project)
end
ee/app/policies/ee/project_policy.rb
rule { security_orchestration_policies_enabled & can?(:guest_access) }.policy do
enable :read_security_orchestration_policy_project
end
This patch aimed to prevent unauthorized users from assigning and accessing the security policy project by checking if they had access permissions to the security policy project. However, even within private projects, guest users can still call the securityPolicyProjectAssign mutation and gain access to the security policy YAML, which they would normally be restricted from viewing.
Note
The previous CVE recognized unauthorized access to security policy YAML as a vulnerability. In GitLab’s issue tracker for #416647 (comment 1452019550), comments specify that the security policy YAML could contain sensitive variables, which should be considered a vulnerability. Dominic Bauer explains:
“I believe we could consider it as a vulnerability, as potential variables could be stored in these policies and leaked as a result.”
Therefore, this report should also be treated as a vulnerability.
Here are the steps to reproduce this vulnerability:
-
Set Up Victim User.
• The victim user creates a group (e.g., victim-corp).
• Within this group, they create a new project (e.g., victim-security-policy-project).
• The victim user sets up a security policy in this project with the following YAML configuration:
approval_policy:
- name: test
description: test
enabled: true
rules:
- type: any_merge_request
branch_type: protected
commits: any
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- owner
- type: send_bot_message
enabled: true
approval_settings:
block_branch_modification: true
prevent_pushing_and_force_pushing: true
prevent_approval_by_author: true
prevent_approval_by_commit_author: true
remove_approvals_with_new_commit: true
require_password_to_approve: false
fallback_behavior:
fail: closed
2. Invite Attacker as Guest.
• The victim user invites the attacker (e.g., User B) to the victim-security-policy-project with guest permissions.
3. Attacker Creates Their Own Group and Project.
• The attacker creates a new group (e.g., attacker-corp) and a new project within this group.
• Attempting to assign the victim’s security policy project to their project through the UI will fail due to access restrictions.
4. Exploiting the Vulnerability via GraphQL.
• The attacker uses the GraphQL Explorer (e.g., https://gitlab.com/-/graphql-explorer) to obtain the ID of the victim’s security policy
project.
query {
project(fullPath: "victim-corp/victim-security-policy-project") {
id
}
}
• With the acquired ID (e.g., gid://gitlab/Project/64192849), the attacker executes the following securityPolicyProjectAssign mutation to assign the victim’s security policy project to their own project:
mutation {
securityPolicyProjectAssign(input: { fullPath: "attacker-corp/attacker-project", securityPolicyProjectId: "gid://gitlab/Project/64192849" }) {
errors
}
}
- Verification
• The attacker navigates to Secure > Policies in their project (attacker-project) and verifies that the security policy from the victim project is visible.
Example policy displayed in the attacker’s project:
Using this vulnerability, an attacker with only guest permissions can directly call the securityPolicyProjectAssign mutation to view the YAML contents of another project’s security policy, bypassing typical access controls.
Impact
Guest user can Read Security Policy YAML
Results of GitLab environment info
This issue occurs in GitLab.
Impact
Guest user can Read Security Policy YAML
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: