# Send arbitrary PUT requests when user clicks on a link

Mermaid class names let attacker inject js-issuable-actions/btn-close classes so a click sends an arbitrary PUT request as the victim.

- Payout: hidden
- Severity: medium
- Program: GitLab
- Found by: yvvdwf
- Disclosed: 2020-07-27
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/824689
- Library page: https://bugbountylibrary.com/r/h1%3A824689
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:medium tech:rest technique:chained technique:source-review vuln:csrf

**Target:** GitLab issue description Mermaid rendering / issue.js click handler
**Root cause:** Mermaid lets users assign arbitrary CSS class names to graph nodes; issue.js binds a click handler to .js-issuable-actions a.btn-close and PUTs to the element's href, so attacker-controlled classes turn a Mermaid node into a PUT trigger.
**Steps:**
1. Create any issue.
2. Set description to a mermaid block: `graph TD; A[Click to send a PUT request]; class A js-issuable-actions; class A btn-close; click A "./put-destination" "click to PUT"`.
3. Save the issue.
4. Click the rendered block; a PUT request is sent to `./put-destination`.
5. Point destination at e.g. `/api/v4/projects/16210710/issues/2?description=a` to modify issue #2 as the victim.
**How found:** Code-reading of issue.js#L90 revealed a delegated click handler on .js-issuable-actions a.btn-close that PUTs to the element's href; combined with Mermaid's ability to set arbitrary class names on nodes, the researcher realized a Mermaid block could masquerade as that button.
**Exploitation:** Attacker crafts a Mermaid node carrying the js-issuable-actions and btn-close classes and a click link to an arbitrary relative URL; when a victim clicks the node, issue.js's delegated handler issues axios.put(url) with the victim's session, allowing state-changing PUT requests such as editing issue descriptions via the API.
**Insight:** When a UI framework lets users assign arbitrary CSS classes (Mermaid class, markdown attributes), audit delegated jQuery handlers keyed on class selectors that read href and perform state-changing requests — user-controlled classes can hijack them.

