Skip to content

Webhook token leaked in project exports allowing to trigger CI pipeline

HackerOne report #698068 by xanbanx on 2019-09-19, assigned to @jritchey:

Hi GitLab Security Team,

Summary

When exporting a Github connect repository within GitLab, the project export contains the external_webhook_token. This token allows anyone in possession to forge authentic requests to trigger a CI pipeline within GitLab although the person might not be a project member anymore.

Steps to reproduce

Tested on GitLab Enterprise Edition 12.3.0-pre 32dae283

Before, create a Github account, create a project there, and push a valid .gitlab-ci.yml file.

  1. Create a new project. Chose CI/CD for external repo to import a project
  2. Chose Github under Connect repositories from
  3. Enter your personal access token from your GitHub account where you want to import the project from
  4. Select the project you created before Github for sync
  5. After importing the project, goto https://example.gitlab.com/<namespace>/<project>/edit and export the project
  6. Download the project archive, extract it, and inspect the containing project.json
...  
    "jobs_cache_index": null,  
    "external_authorization_classification_label": "",  
    "external_webhook_token": "hcnPbsfximlueXxaaIkg",  
    "pages_https_only": true,  
    "merge_requests_author_approval": null,  
...  

Note, this is a fake token for the report.

When looking in the code one observes the request POST :id/mirror/pull in https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/api/project_mirror.rb#L59. This request is used to trigger a new pipeline for a Github connected repository. This request uses the X-Hub-Signature header to authenticate the request to create the pipeline. This signature is computed by computing an HMAC over the request data using external_webhook_token as the key.

By being in possession of external_webhook_token it means that you craft a request and forge a valid X-Hub-Signature to create a new pipeline. So anyone, who can download the project can later on, when for example he is not a project member anymore, craft such a request and thereby trigger a pipeline.

Impact

The external external_webhook_token is exported. This allows anyone in possession of this token to forge a valid POST request to trigger a new CI pipeline. In the worst case, an attacker can possibly create thousands of CI pipelines and thus DoS the CI infrastructure.

What is the current bug behavior?

The project export contains external_webhook_token. This allows anyone to forge a POST request to start a new pipeline.

What is the expected correct behavior?

Do not include the external_webhook_token in the project export. Anyway, it is not useful because this secret is bound to one specific webhook at Github, which still points to the original GitLab project. Importing the project to a different namespace or different GitLab instance would therefore make this token not working anymore.

Output of checks

This bug happens on GitLab.com

Best regards,
Xanbanx

Impact

See above.

Implementation plan

Edited by Alan (Maciej) Paruszewski