Sunday 1 July 2012

Vintage XSS (Expect Header Cross Site Scripting)

The Expect Header is vulnerable to Cross Site Scripting. The vulnerability was detected in Apache (httpd) way back in 2006. That's the reason I've called this as Vintage XSS, as it is an old one and not been found on latest versions. 

Here is the Expect Header definition from W3C :-

The Expect request-header field is used to indicate that particular server behaviors are required by the client.   
      Expect       =  "Expect" ":" 1#expectation   
      expectation  =  "100-continue" | expectation-extension
      expectation-extension =  token [ "=" ( token | quoted-string )
                               *expect-params ]
      expect-params =  ";" token [ "=" ( token | quoted-string ) ]      
A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a request MUST respond with appropriate error status. The server MUST respond with a 417 (Expectation Failed) status if any of the expectations cannot be met or, if there are other problems with the request, some other 4xx status.
 
This header field is defined with extensible syntax to allow for future extensions. If a server receives a request containing an Expect field that includes an expectation-extension that it does not support, it MUST respond with a 417 (Expectation Failed) status.
 
Comparison of expectation values is case-insensitive for unquoted tokens (including the 100-continue token), and is case-sensitive for quoted-string expectation-extensions.
 
The Expect mechanism is hop-by-hop: that is, an HTTP/1.1 proxy MUST return a 417 (Expectation Failed) status if it receives a request with an expectation that it cannot meet. However, the Expect request-header itself is end-to-end; it MUST be forwarded if the request is forwarded.
 
Many older HTTP/1.0 and HTTP/1.1 applications do not understand the Expect header.

The most important thing here is that when the Server does not comply with the Expect field of a request, it MUST respond with a 417 "Expectation Failed" response. 

The vulnerability lies in the fact that the response from the server contains the Expect Header as sent in the request. If this field is is included in the response without data validation, so it can be exploited for an XSS.


Here is an example POC (Proof of Concept):-

Shown below is a request to the server that does not handle the Expect Header :-




Now, here is the 417 (Expectation Failed) response from the server. Notice the special characters are reflected back as it is from the request. This means no filtering of data.




Basically we can exploit this behavior for a simple Reflected Cross Site Scripting.

As shown in the below POC just add a SCRIPT Tag in the Expect Header :-





The server returns the unvalidated data, causing the script to execute :-




The solution for this is to upgrade your server to the latest version available.