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
- Create two users, "Max" and "Moritz".
- Login as Max.
2.1 Create a new project.
2.2 Create a random commit onmasterbranch and tag that one asv0.0.1.
2.3 Create a CI/CD variable with key "SECRET" and set it to protected state.
2.4 Add wildcardv*to list of protected tags.
2.5 Invite Moritz as Developer to the project. - Login as Moritz.
3.1 Accept the invitation to the project.
3.2 Create a.gitlab-ci.ymlwith 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!