Two HTTP Header Injection vulnerabilities have been discovered by Rapid7
in the Flash Player plugin. They allow attackers to perform arbitrary
HTTP requests while controlling most of the HTTP headers. This can make
it easier to perform CSRF attacks [2] in some cases. When the HTTP
server implements Keep-Alive connections and when Firefox is used, these
Flash vulnerabilities can even be used to perform totally arbitrary HTTP
requests where every part is controlled by the attacker: HTTP method,
URI, HTTP version, headers, and data. Such attacks make use of the HTTP
Request Splitting method.

Flash features a scripting language called ActionScript. ActionScript
comes with a certain number of standard classes available to Flash
developers. In particular, the send() method of the XML object can be
used to send XML document trees to arbitrary URLs using, by default, a
POST request. This, in itself, is not a vulnerability; the XML.send()
method definitely complies with the Flash security model [4].

However another method defined in the XML class, addRequestHeader(), can
be used to add arbitrary HTTP headers to the request performed by Flash.
Its intended usage is:

For this attack to work, the first argument of addRequestHeader() must
not contain any space (ASCII 0x20) else the Flash plugin appears to
ignore the addRequestHeader() call. This is absolutely not a problem in
real-world attack scenarios, because the space character usually present
before the Referer value is optional (see RFC 2616 [5], section "4.2
Message Headers").

It is interesting to note that IE seems to post-process the headers
generated by Flash before sending them to the HTTP server. Indeed, IE
diligently removes the real Referer to use the Flash-generated one, and
it even automatically adds the optional space character before the fake
Referer value.

Of course any cookie that would be associated with 'host' would be
automatically sent along with the request, which is another good thing
for attackers.

For total control of the generated request, when the server supports
keep-alive connections and when Firefox is used, it is possible to use
the HTTP Request Splitting method to insert another HTTP request:

Tabs (ASCII 0x09) have to be used around the URI ("/anotherpath")
instead of spaces (ASCII 0x20) else, as explained above, Flash ignores
the addRequestHeader() call. But other than this minor inconvenient,
pretty much any other character can be sent, absolutely nothing is
URL-encoded, which gives plenty of freedom to attackers.

The unwanted data after "foo" (": bar\r\nContent-length: 4\r\n\r\ntest")
do not create any problem at all either. Because the attacker-controlled
"Content-Length:3" header takes care of instructing the server to ignore
any subsequent data.

When trying to use this HTTP Request Splitting method with IE, it fails
with a generic "The page cannot be displayed" error. This is probably
due to the fact that when IE post-processes the headers (as explained
previously), it messes up the manually built HTTP request and ends up
with something that doesn't look like 2 valid requests at all. In
particular, what seems to trigger this error is the CR LF CR LF sequence
separating the headers from the body. This issue has not been
investigated any more. More research is necessary to determine if
exploiting IE this way is possible.

It should be pointed out that this new Flash 9 XML.addRequestHeader()
vulnerability is similar to other, previously reported vulnerabilities
in Flash 7 & 8 affecting the LoadVars class, as explained in this
Bugtraq posting from Amit Klein [1]. So, in a certain way, this new
vulnerability re-opens a path of exploitation that was available to
attackers in Flash 7 & 8.

5.2. XML.contentType Vulnerability

The XML class defines the contentType attribute, which can be set by
Flash developers, e.g.:

req.contentType = "text/plain";

The exact same vulnerability than the one described in the previous
section also exists for this attribute: Flash does not check the
validity of its value before building the HTTP request. It is possible
to exploit it in the same way that addRequestHeader() is used:

req.contentType = "text/plain\r\nReferer: anything";

Contrary to addRequestHeader(), Flash allows spaces (ASCII 0x20) to be
used in this string.

5.3 Consequence

The consequence of these vulnerabilities is that attackers have a lot
more control on the headers that get sent along with HTTP requests,
compared to what is commonly thought possible. In particular the Host,
Referer, and User-Agent headers can be spoofed. It is even possible to
voluntarily generate malformed HTTP requests too, when the HTTP Request
Splitting method is used.

But when combined with other flaws, such as XSS or CSRF, these Flash
vulnerabilities become a handy tool to exploit them. The next section
describes a CSRF attack scenario.

6. Exploitation Example

6.1. Description of CSRF Attacks

A Cross-Site Request Forgery (CSRF) is a form of attack where a
malicious site A exploits the trust a site B has in a user by forging an
HTTP request and sending it to site B, which sees it as coming from its
trusted user. See [2] for a more detailled description of CSRF attacks.

The Flash vulnerabilities presented above can help attackers forge such
HTTP requests.

Multiple approaches exist to prevent CSRF attacks, offering varying
levels of protection. For example requiring POST requests instead of GET
requests is a very poor way to protect against them. Other times, the
protection chosen by web site developers is to check for the HTTP
Referer. The assumption is that spoofing the Referer header is much
harder, but not impossible. These Flash vulnerabilities are able to
spoof it.

A much better way to protect against CSRF attacks is to require the use
of a security hash, as described in [3].

6.2. Attack Scenario

Let's say a malicious attacker is able to convince a user to visit his
malicious website http://malicious. The intent of the attacker is to
perform a CSRF attack against the user's bank website https://bank to
silently transfer money from the user's account to the attacker's
account. This attack assumes that (1) the bank uses SSL/TLS (HTTPS)
combined with cookie-based authentication, (2) checks the Referer header
to prevent CSRF attacks (hopefully no bank is doing this), and (3) that
a money transfer order can be initiated via such an HTTP request:

The attack also assumes the user is using Firefox, because we are going
to use the CR LF CR LF sequence with addRequestHeader() to insert the
HTTP body data (as explained in section 1.1 this sequence does not work
with IE for an unknown reason).

We have to insert the HTTP body using addRequestHeader() because this
way the body doesn't get URL-encoded by Flash (it is URL-encoded when
passed as a string to the XML() constructor).

And we have to prevent URL-encoding in order to preserve the ampersands
("&") present in the body ("from=...&to=...").

So, in order to perform the attack, the attacker would have to place a
Flash movie on http://malicious containing this ActionScript code:

Then, when the user would visit http://malicious, assuming his browser
still owns an unexpired cookie from the bank, this request would be sent
via HTTPS (XML.send() allows an HTTP site to send data over HTTPS):

Rapid7, LLC is not responsible for the misuse of the information
provided in our security advisories. These advisories are a service to
the professional security community. There are NO WARRANTIES with regard
to this information. Any application or distribution of this information
constitutes acceptance AS IS, at the user's own risk. This information
is subject to change without notice.

This advisory Copyright (C) 2006 Rapid7, LLC. Permission is hereby
granted to redistribute this advisory, providing that no changes are
made and that the copyright notices and disclaimers remain intact.