Maintainer can change the visibility of Project and Group
HackerOne report #1536559 by suruli
on 2022-04-10, assigned to GitLab Team
:
Report | Attachments | How To Reproduce
Report
Hi, According to gitlab docs, api and web_ui, a maintainer of a project is restricted from changing its visibility. The check for user permission is done after making sure the new_visibility is different from current_visibilty level of the project.
### gitlab-development-kit/gitlab/app/services/concerns/update_visibility_level.rb
def valid_visibility_level_change?(target, new_visibility)
return true unless new_visibility
new_visibility_level = Gitlab::VisibilityLevel.level_value(new_visibility)
if new_visibility_level != target.visibility_level_value #target.visibility_level_value is 0 for private projects and groups
unless can?(current_user, :change_visibility_level, target) &&
Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility_level)
deny_visibility_level(target, new_visibility_level)
return false
end
end
true
end
### gitlab-development-kit/gitlab/lib/gitlab/visibility_level.rb
PRIVATE = 0 unless const_defined?(:PRIVATE)
INTERNAL = 10 unless const_defined?(:INTERNAL)
PUBLIC = 20 unless const_defined?(:PUBLIC)
def string_options
{
'private' => PRIVATE,
'internal' => INTERNAL,
'public' => PUBLIC
}
end
def level_value(level)
return level.to_i if level.to_i.to_s == level.to_s && string_options.key(level.to_i)
string_options[level] || PRIVATE
end
The level_value
method returns 0 (the value of PRIVATE) for any input except 10, 20, 'internal', 'public'
. For a private project or group, passing the new_visibility as 20r
to the method level_value
will return 0 that bypasses the check for user permission and then '20r'.to_i
is 20 (PUBLIC) will be assigned as project visibility.
Requirements:
- Two gitlab accounts (Eg, victim_account and attacker_account).
- Burp or similar.
Steps to reproduce
Victim:
- Login to victim_account and goto
New project
>Create blank project
- Give any
Project name
. Make sureProject URL
has victim's username and clickCreate project
- Visit the created project and goto
Project Information
>Members
from the side menu. Clickinvite members
. - Enter the attacker_account's username or email address. Select the role
Maintainer
and clickInvite
.
Attacker:
- Visit the victim's project from attacker_account.
- Goto
Settings
>General
from side menu. - Expand
Visibility, project features, permissions
section. - Turn the Burp intercept on and click
Save changes
at the bottom of that section.
Example Request
POST /victim-namespace/victim-project-slug HTTP/2
.
.
.
.
.
-----------------------------31179005449602053611562110226
Content-Disposition: form-data; name="_method"
patch
-----------------------------31179005449602053611562110226
Content-Disposition: form-data; name="update_section"
js-shared-permissions
-----------------------------31179005449602053611562110226
Content-Disposition: form-data; name="project[request_access_enabled]"
true
-----------------------------31179005449602053611562110226
Content-Disposition: form-data; name="project[project_feature_attributes][issues_access_level]"
20
-----------------------------31179005449602053611562110226
.
.
.
-----------------------------31179005449602053611562110226--
- Add the following value to the request along with the form boundary and
Send
the request.
Content-Disposition: form-data; name="project[visibility_level]"
20r
Other visibility levels can also be set by replacing the value 20r
with following values.
current visibility > input > resulting visibility
private>20r
>public
private>10r
>internal
public > public
> private
internal > internal
> private
- Refresh the page to see the change of
Project visibility
.
The same steps can be repeated for Groups as well.
What is the current bug behavior?
user permission is checked after the check for inequality of new and current visibility level.
What is the expected correct behavior?
user permission should be checked before the check for inequality.
Installed fresh gitlab instance from https://about.gitlab.com/install/#ubuntu on the date of the report.
Impact
A Maintainer can change:
Visibility of Projects and Groups in Self-managed Gitlab instance.
Visibility of Projects in gitlab.com.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: