Skip to content

HTML injection in Global Search, can lead to XSS with CSP bypass in MR diff view

Please read the process on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.

HackerOne report #2659386 by joaxcar on 2024-08-14, assigned to @kmorrison1:

Report | Attachments | How To Reproduce

Report

Summary

An HTML injection exists in the "global search" popup when searching for files.

This is the sink in app/assets/javascripts/super_sidebar/components/global_search/command_palette/search_item.vue

 highlightedName() {  
      return highlight(this.item.text, this.searchQuery);  
    },

...

<span v-safe-html="highlightedName" class="gl-text-gray-900"></span>  

the item.text is generated in app/assets/javascripts/super_sidebar/components/global_search/command_palette/utils.js

export const fileMapper = (projectBlobPath, file) => {  
  return {  
    icon: 'doc-code',  
    text: file,  
    href: joinPaths(projectBlobPath, file),  
    extraAttrs: {  
      'data-track-action': TRACKING_CLICK_COMMAND_PALETTE_ITEM,  
      'data-track-label': 'file',  
    },  
  };  
};  

the data sent into here comes from here app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue

const response = await axios.get(this.projectFilesPath);  
          this.projectFiles = response?.data.map(fileMapper.bind(null, this.projectBlobPath));  

This means that filenames are sent directly into v-safe-html and filenames can contain HTML

One place in the app where this can lead to XSS in new merge request diff pages bypassing CSP on gitlab.com

Steps to reproduce

  1. Go to https://gitlab.com/-/snippets/new and create a new public snippet with a file called alert.json and the content
{"html":"<script>alert(document.domain)</script>"}  

take note of the snippet ID
2. Create a new project
3. In the project create a file with this name (replace 3737908 with your snippet ID)

<i class=inline-parallel-buttons><a href=\-\snippets\3737908\raw\main\alert style="position:fixed;transform:translate3d(-2000px,-5000px,0px);width:10000px;height:20000px">  
  1. Go to https://gitlab.com/GROUPNAME/PROJECTNAME/-/new/main and create a new file, fill out whatever but make sure to change the target branch from main to new_branch. Keep "start a new merge request" checked.
  2. Click commit changes
  3. Go to https://gitlab.com/GROUPNAME/PROJECTNAME/-/merge_requests/new/diffs?merge_request%5Bsource_branch%5D=new_branch&merge_request%5Btarget_branch%5D=main (note that the source_branch%5D=new_branch if you did not name your branch like this in step 4)
  4. Click Search or go to.. in the upper left corner (or click / or s which are shortcuts)

Screenshot_2024-08-14_at_23.40.46.png

  1. In the search box type ~
  2. There should now be some result in the search list, but it will be the HTML that is now covering the whole page
  3. Click anywhere on the page, and an alert box should pop

Screenshot_2024-08-14_at_23.42.50.png

Impact

XSS with CSP bypass on gitlab.com

What is the current bug behavior?

Filenames are not escaped in global search

What is the expected correct behavior?

Filenames should not render as HTML

Output of checks

This bug happens on GitLab.com

Impact

XSS with CSP bypass on gitlab.com

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section: