CSP-bypass XSS in project settings page
HackerOne report #1588732 by yvvdwf
on 2022-06-01, assigned to GitLab Team
:
Report | Attachments | How To Reproduce
Report
Summary
This javascript function is vulnerable:
deployKeyRowHtml(key, isActive) {
const isActiveClass = isActive || '';
return `
<li>
<a href="#" class="${isActiveClass}">
<strong>${key.title}</strong>
<p>
${sprintf(
__('Owned by %{image_tag}'),
{
image_tag: `<img src="${key.avatar_url}" class="avatar avatar-inline s26" width="30">`,
},
false,
)}
<strong class="dropdown-menu-user-full-name gl-display-inline">${escape(
key.fullname,
)}</strong>
<span class="dropdown-menu-user-username gl-display-inline">${key.username}</span>
</p>
</a>
</li>
`;
}
It is used to render a deployment key in a dropdown item. Because the deployment title is controlled by users, it can be any html content, such as, <script>alert(document.domain)</script>
. Furthermore, the html content will be rendered using jQuery, so the <script>
tag will be executed despise of CSP with script-src
having 'strict-dynamic'
value:
renderMenu(html) {
if (this.options.renderMenu) {
return this.options.renderMenu(html);
}
return $('<ul>').append(html);
}
Steps to reproduce
- In an existing project or create a new one, goto
Settings
/Repository
. Then fill the form inDeploy keys
as the following:
-
Title
:test <script>alert(document.domain)</script>
-
Key
:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkhkyrQJvb30Q5lLZzxeALqCyBrLOh+QzRYWh+gPGpqi2efyGMf5beN2zda66OI6DaclB31SJ0jYzaYKgKXQw7rzu/IYazONdy5lz5O2iUB2BkDzJYZ+BObTaTCjyDgSvNNuezUqNXXqoXftEMa1l0+FRSkTusH5F2P3JCV3Tf1BBQImrbDIpdc6ps+UxsiX7S/dT+7bNIVXblC8s8k+AK4CWsC2KmfMToK35pk+sa9JI+rb26hzv8IHA8n7cqXOmR5qAj2qX962p1kOLNXCyHJAKAIfRXCuDPbXiB+kjnu478eIcudOPveo3CK3G6hBI0hPSRfoyAUIubcddnnbhR
-
Grant write permissions to this key
: Checked
Then click Add key
button to save the form.
NOTE:
-
Title
can be any HTML content that represents the attack payload. In the example above, we just show an alert containing the current domain. -
Key
can be any valid SSH public key. In the example above, I give you a random key so that you can copy-paste into the form without the need to generate a key
- Always in the
Settings
/Repository
page, click onProtected branches
link to expand its form - Click on the dropdown box under
Allowed to push
, you should see an alert that was generated when the payload above being executed
NOTE:
- This is not self-XSS as any project maintainer can access to the settings page. Furthermore a victim can be added as a project maintainer without their explicit acceptation
- The Step 2 can be ignored by accessing directly within
#js-protected-branches-settings
on the url, for example,https://gitlab.com/yvvdwf/xss/-/settings/repository#js-protected-branches-settings
Impact
XSS with CSP bypass allows attacks to perform arbitrary malicious requests on behalf of victims on HTTP client side, such as, do an API request to access to private resources, etc.
Examples
https://gitlab.com/yvvdwf/xss/-/settings/repository#js-protected-branches-settings
What is the current bug behavior?
Deployment title is not sanitized
What is the expected correct behavior?
Deployment title should be sanitized
Output of checks
This bug happens on GitLab.com
Impact
XSS with CSP bypass allows attacks to perform arbitrary malicious requests on behalf of victims on HTTP client side, such as, do an API request to access to private resources, etc.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: