Protected CI variables are leaked to an attacker which has the right to create a branch in the repository

HackerOne report #692010 by jelhan on 2019-09-10, assigned to hackerjuan:

Summary

GitLab CI treats a branch as a tag if there is a naming collision between the branch and an existing tag. If that tag is protected, GitLab CI handles a commit to that branch as if the CI pipeline runs for a protected tag. This gives an attacker access to protected variables by creating a branch with the same name as an existing protected tag.

Steps to reproduce

  1. Create two users, "Max" and "Moritz".
  2. Login as Max.
    2.1 Create a new project.
    2.2 Create a random commit on master branch and tag that one as v0.0.1.
    2.3 Create a CI/CD variable with key "SECRET" and set it to protected state.
    2.4 Add wildcard v* to list of protected tags.
    2.5 Invite Moritz as Developer to the project.
  3. Login as Moritz.
    3.1 Accept the invitation to the project.
    3.2 Create a .gitlab-ci.yml with following content:
    job:  
      script: "echo $SECRET"  
      variables:  
        GIT_STRATEGY: clone  
        GIT_CHECKOUT: "false"  

3.3 Commit the .gitlab-ci.yml to a feature branch called v0.0.1.
3.4 Read the protected CI variable in CI logs.

Examples

I've reproduced the bug on gitlab.com with a private project: https://gitlab.com/jelhan/test-ci
For this reproduction @jelhan is Max and @jelhan-test is Moritz from above reproduction steps. Please find a screencast taken while doing the reproduction using that repo attached.

What is the current bug behavior?

A user not being able to create a protected branch/tag could control the .gitlab-ci.yml that is executed in the context of a protected branch/tag. An attacker could use this to gather access to protected CI variables.

What is the expected correct behavior?

A CI pipeline triggered by a commit to a branch, which is not protected, should not have access to protected CI variables even if there is a naming collision with with a protected tag.

Related security issue

The same issue will also cause a CI pipeline that should be limited to tags be triggered by a commit to a feature branch named as an existing tag. This is a security issue for projects that limit the permissions to create a tag to maintainers. This could be done by using "*" wildcard as protected tag. An attacker would be able to trigger a CI pipeline that is limited to tags even if he's not able to create a tag. I think the reproduction for this one is quite obvious.

Impact

An attacker having the permission to create a branch could get access to protected CI variables. Additionally he could trigger a CI pipeline for a tag even if he hasn't the permission to create any tag.

The issue is mitigated by the fact that an attacker must have permissions to create a branch and that a protected tag must exist, which name does not match a protected branch. Until a fix is released protected tags could be configured to be a subset of protected branches as a protection against this security issue.

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

  • gitlab-leaks-protected-ci-variable.mp4
Assignee Loading
Time tracking Loading