Repo information leaked when repo access is set to project members only
HackerOne report #460344 by xanbanx on 2018-12-11:
Summary
GitLab allows to set the repository permissions of a project to Only Project Members
. This prevents unauthorized users to gain access to repository information. However, there is some repository information, which is leaked via the project API. In particular, non-project members of public projects have access to:
- The default branch
- The commit statistics
Both information is available via the V4 REST API. The default branch is also available via the GraphQL API.
Steps To Reproduce:
Reproduced on GitLab 11.6.0-rc4-ee
- Create a public project (in this case name
test-default-branch
) and set the repository access toOnly Project Members
- Login as a second user, which is not a member of the project
- With the second user, perform the following API query (substitute the project-id with the ID of the project created in step 1):
curl --header "PRIVATE-TOKEN: <your-PAT>" "https://gitlab.example.com/api/v4/projects/<project-id>?statistics=true"
This will return following JSON response:
{
"id": 17,
"description": "",
"name": "test-repo",
"name_with_namespace": "xanbanx / test-repo",
"path": "test-repo",
"path_with_namespace": "xanbanx/test-repo",
"created_at": "2018-12-11T11:25:29.011Z",
"default_branch": "master",
"tag_list": [],
"ssh_url_to_repo": "git@example.gitlab.com:xanbanx/test-repo.git",
"http_url_to_repo": "https://example.gitlab.com/xanbanx/test-repo.git",
"web_url": "https://example.gitlab.com/xanbanx/test-repo",
"readme_url": null,
"avatar_url": null,
"star_count": 0,
"forks_count": 0,
"last_activity_at": "2018-12-11T11:25:29.011Z",
"namespace": {
"id": 13,
"name": "xanbanx",
"path": "xanbanx",
"kind": "user",
"full_path": "xanbanx",
"parent_id": null
},
"_links": {
"self": "https://example.gitlab.com/api/v4/projects/17",
"repo_branches": "https://example.gitlab.com/api/v4/projects/17/repository/branches",
"labels": "https://example.gitlab.com/api/v4/projects/17/labels",
"events": "https://example.gitlab.com/api/v4/projects/17/events",
"members": "https://example.gitlab.com/api/v4/projects/17/members"
},
"archived": false,
"visibility": "public",
"owner": {
"id": 3017950,
"name": "xanbanx",
"username": "xanbanx",
"state": "active",
"avatar_url": "https://secure.gravatar.com/avatar/6466f73ed21b9d1624dee906921e9176?s=80&d=identicon",
"web_url": "https://example.gitlab.com/xanbanx"
},
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": true,
"issues_enabled": false,
"merge_requests_enabled": false,
"wiki_enabled": false,
"jobs_enabled": false,
"snippets_enabled": false,
"shared_runners_enabled": true,
"lfs_enabled": true,
"creator_id": 3017950,
"import_status": "none",
"public_jobs": true,
"ci_config_path": null,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
"request_access_enabled": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"printing_merge_request_link_enabled": true,
"merge_method": "merge",
"statistics": {
"commit_count": 1,
"storage_size": 83886,
"repository_size": 83886,
"lfs_objects_size": 0,
"job_artifacts_size": 0
},
"permissions": {
"project_access": null,
"group_access": null
},
"approvals_before_merge": 0,
"mirror": false,
"external_authorization_classification_label": "",
"packages_enabled": true
}
This includes the statistics, showing the repo size and number of commits. Furthermore, the default branch is shown. Both information should be private then the repo permission is set to `Project Members Only.
Accessing the default branch is also possible via the new GraphQL API. Therefore, perform the following query (substitute the fullPath
with the path of the project created in step 1):
{
project(fullPath: "xanbanx/test-repo") {
id
name
defaultBranch
}
}
This will return the following response including the default branch:
{
"data": {
"project": {
"id": "17",
"name": "test-repo",
"defaultBranch": "master"
}
}
}
Steps to mitigate
When repo access is set to Project Members Only
, do not show repository related information. Instead leave them blank with a null
value,
Impact
Any user can see the default branch and the commit statistics of the repo although the user does not have repository access.