# Security Vulnerability in GitLab: Sending Arbitrary Requests through Jupyter Notebooks

GitLab's Jupyter notebook viewer rendered unsanitized HTML; jquery-ujs data-* attributes let a notebook issue arbitrary authenticated API requests, e.g. adding the attacker as project maintainer.

- Payout: unconfirmed
- Severity: high
- Program: GitLab
- Credited: Daniel Fürst
- Disclosed: 2022-06-07
- Write-up quality: 7/10
- Original: https://liman.io/blog/gitlab-security-vulnerability-jupyter-notebooks
- Library page: https://bugbountylibrary.com/r/blog%3Aliman-io-blog-gitlab-security-vulnerability-jupyter-notebooks
- Tags: domain:web impact:integrity impact:privesc kind:bounty platform:blog sev:high tech:ruby technique:chained technique:source-review vuln:csrf vuln:xss

**Target:** Jupyter notebook rich representation viewer (web)
**Root cause:** The notebook viewer rendered markdown cell HTML without sanitization, and GitLab's bundled jquery-ujs honored data-method/data-params/data-remote/data-url attributes on injected anchors.
**Steps:**
1. Create a Jupyter notebook with a markdown cell whose source contains an `<a>` with `data-method="put" data-params="message=p0wn3d" data-remote="true" href="/api/v4/user/status"` and full-viewport absolute styling.
2. Commit the notebook to a GitLab project so the rich viewer renders it.
3. Victim opens the notebook; the invisible overlay captures their first click.
4. jquery-ujs fires an authenticated PUT to `/api/v4/user/status` with `message=p0wn3d`.
5. Swap payload to `data-url="/api/v4/projects/<PROJECT_ID>/members"` with `data-params="user_id=<ATTACKER_ID>&access_level=40"` to add attacker as maintainer.
**How found:** Recalled a prior stored XSS in GitLab's OpenAPI rich representation and hypothesized other rich renderers (Jupyter notebook viewer) might lack sanitization; tested HTML in markdown cells and combined with jquery-ujs gadget.
**Exploitation:** Attacker stores a crafted notebook in a project; when a victim views it, a full-page transparent anchor overlay triggers jquery-ujs to send an authenticated same-origin API request on the victim's behalf, performing state changes like status update or adding a maintainer.
**Escalation:** From cosmetic status change to privilege escalation by targeting the project members API with access_level=40 to grant attacker maintainer rights.
**Insight:** When a platform renders multiple 'rich representation' formats, a past XSS in one format is a strong signal to audit the others; also check bundled JS libraries (jquery-ujs) as gadgets that turn benign-looking HTML attributes into authenticated requests.
