Skip to content

Arbitrary HTML injection possible when :soft_email_confirmation feature flag is enabled in the latest release

HackerOne report #1842867 by cryptopone on 2023-01-22, assigned to GitLab Team:

Report | Attachments | How To Reproduce

Report

Summary

In the GitLab 15.8.0 release, changes have been made to https://gitlab.com/gitlab-org/gitlab/-/blob/01cc3a3b45cafda62ea8bc82d5c52278890d8ec8/app/controllers/concerns/confirm_email_warning.rb that includes adding .html_safe to the flash warning. This code is vulnerable on self-managed instances when the :soft_email_confirmation feature flag is enabled on the instance. (GitLab team: Note the .html_safe was part of the original implementation so this issue persists in releases prior to 15.8 and the fixes should be backported to 15.7 and 15.6 accordingly)

  def set_confirm_warning  
    return unless current_user  
    return if current_user.confirmed?

    email = current_user.unconfirmed_email || current_user.email

    flash.now[:warning] = format(  
      confirm_warning_message,  
      email: email,  
      resend_link: view_context.link_to(_('Resend it'), user_confirmation_path(user: { email: email }), method: :post),  
      update_link: view_context.link_to(_('Update it'), profile_path)  
    ).html_safe  
  end  

A malicious user could register an account using an email containing html tags, and these tags will now render in the flash message once the user logs into their account.

Normally this would be considered a self-xss. But if an administrator impersonates the attacker's account, the html/payload will be rendered for the administrator as well. It's also worth noting the additional HTML tags are not visible on the administrator page for the attacker user, so the admin will be unaware of the potential danger of impersonating the account.

Note: This appears to only affect self-managed instances as GitLab.com does not use this feature flag. No CSP bypass is provided at the time this report is filed as GDK is using 'strict-dynamic' which I have been unable to bypass thus far. I found a bypass for source code installs of GitLab with the default CSP set (doesn't use 'strict-dynamic') but I assume GDK is the CSP policy to be testing against.

Steps to reproduce
Prerequisites:
  1. Enable the feature flag :soft_email_confirmation on the GitLab instance. (ex. Run gitlab-rails console then execute Feature.enable(:soft_email_confirmation) inside the rails console).
  2. Go to the Admin general settings page (http://gitlab.example.com/admin/application_settings/general).
  3. Expand sign-up restrictions and set "Email confirmation settings" to "Hard".
  4. Save the changes.
Reproduction Steps (Attacker):
  1. Register an account on the instance. (ex. Username: AttackerSoftEmail, Email: attackersoftemail@example.com)
  2. Log into the account. You should now see a message at the top of the screen stating "Please check your email (attackersoftemail@example.com) to verify that you own this address and unlock the power of CI/CD. Didn't receive it? Resend it. Wrong email address? Update it."
  3. Go to the user's profile (http://gitlab.example.com/-/profile)
  4. Change your e-mail by appending <h2>testing</h2><script>alert(document.domain)</script> to the end of the address.
  5. Save the changes.
  6. Each time the page reloads, you will see a javascript alert fire.
Reproduction Steps (Victim Administrator):
  1. Log into GitLab as root.
  2. Navigate to the Admin users panel and select the AttackerSoftEmail user (http://gitlab.example.com/admin/users/AttackerSoftEmail).
  3. Note the email address for AttackerSoftEmail does not contain HTML.
  4. Click the "Impersonate" button to begin impersonating the user.
  5. Note the javascript fires as the page is loaded.
  6. Close the alert box, and see the HTML header tag rendered as the page loads.
Impact

Administrators on self-managed instances impersonating the attacker's account will inadvertently trigger XSS if the attacker has not validated their email and :soft_email_confirmation feature flag is enabled on an instance that requires email confirmations upon registration.

The Administrator is not made aware of the HTML payload contained in the attacker's email address when viewing the attacker's profile from the administrator user page.

Examples

N/A

What is the current bug behavior?

XSS is triggered within context of the self-hosted GitLab instance.

What is the expected correct behavior?

HTML code appended to the email address should not be rendered by the browser when users are presented with the soft email confirmation alert.

Relevant logs and/or screenshots

Attacker updates email address containing HTML payload.
AttackerWithHTMLTagsInUpdatedEmail.png

Administrator views the attacker's account in the admin user menu. Note the page does not display the HTML included in the attacker email.
AdministratorViewingUserProfileWithoutSeeingEmailTags.png

As soon as the administrator impersonates the user they trigger the XSS payload.
AdministratorImpersonatingUserTriggeringXSS.png

Administrator impersonates the attacker account, triggering the attacker's payload as soon as the account is impersonated.
AdministratorImpersonatingAttackerAccount.png

Finally, a video demonstrating the attack and victim triggering the XSS payload
SoftEmailConfirmation_repro.mp4

Output of checks
Results of GitLab environment info
System information  
System:		Ubuntu 20.04  
Proxy:		no  
Current User:	git  
Using RVM:	no  
Ruby Version:	2.7.7p221  
Gem Version:	3.1.6  
Bundler Version:2.3.15  
Rake Version:	13.0.6  
Redis Version:	6.2.8  
Sidekiq Version:6.5.7  
Go Version:	unknown

GitLab information  
Version:	15.8.0-ee  
Revision:	1d89c23c9f9  
Directory:	/opt/gitlab/embedded/service/gitlab-rails  
DB Adapter:	PostgreSQL  
DB Version:	12.12  
URL:		https://gitlab-pentest2.example.com  
HTTP Clone URL:	https://gitlab-pentest2.example.com/some-group/some-project.git  
SSH Clone URL:	git@gitlab-pentest2.example.com:some-group/some-project.git  
Elasticsearch:	no  
Geo:		no  
Using LDAP:	no  
Using Omniauth:	yes  
Omniauth Providers: 

GitLab Shell  
Version:	14.15.0  
Repository storages:  
- default: 	unix:/var/opt/gitlab/gitaly/gitaly.socket  
GitLab Shell path:		/opt/gitlab/embedded/service/gitlab-shell  

Impact

Administrators on self-managed instances impersonating the attacker's account will inadvertently trigger XSS if the attacker has not validated their email and :soft_email_confirmation feature flag is enabled on an instance that requires email confirmations upon registration.

The Administrator is not made aware of the HTML payload contained in the attacker's email address when viewing the attacker's profile from the administrator user page.

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section:

Edited by Adil Farrukh