[WEB SECURITY] ERRATA (Re: [WEB SECURITY] Write-up by Amit Klein: "Forging HTTP request headers with Flash")

Amit Klein (AKsecurity) aksecurity at hotpop.com
Wed Jul 26 15:40:51 EDT 2006


A reader going by the nickname "xeek" pointed out to me that 
the examples in the paper making use of the HTTP GET request
do not work as-is (thanks xeek!). After looking at the matter,
I realized that I made a silly mistake. In my research, I
toyed with the LoadVars.send() method with 2 arguments 
(url and target window), and had Flash automatically 
select the appropriate methd (GET if empty body, POST if
non-empty body). The exploit works fine this way. When I 
documented my findings, I decided to explicitly add the HTTP
method, to clarify the write-up. BIG mistake - turns out
that in such case, Flash doesn't send the headers if GET is
used (sounds like a bug...). And pity I didn't verify the exact
code I used in the write-up...

Anyway, to summarize - there's a mistake in the document, 
and it's easily fixed. In each GET example, simply remove
the explicit method (i.e. delete all instances of ,"GET" in
the write-up). For example (the first example in the paper):


This works as advertised, and as also verified by xeek.

Thanks, and sorry for the mistake,

On 24 Jul 2006 at 21:29, Amit Klein (AKsecurity) wrote:

>            Forging HTTP request headers with Flash
>                    Amit Klein, July 2006
> Flash - Introduction
> ====================
> Flash player is a very popular browser add-on from Adobe 
> (actually, Flash was invented by Macromedia, which was acquired 
> by Adobe). This write-up covers mostly Flash 7 and Flash 8, 
> together covering more than 94% of the Internet-enabled desktops 
> (according to NPD Online Survey conducted April 2006, quoted in 
> Adobe's website [1], [2]). Flash movies are delivered as SWF 
> (ShockWave File) files. Adobe developed a rich Javascript-like 
> language called ActionScript to provide scripting capabilities to 
> Flash. One of the interesting features of ActionScript is its 
> ability to send HTTP requests to 3rd party sites through the 
> browser which invoked it. This is where Flash becomes interesting 
> security-wise. With Flash it is possible to shape an outgoing 
> request to a 3rd party site in ways not available from within 
> "standard" Javascript. Specifically of interest is Flash's 
> ability to send arbitrary HTTP request headers with outgoing HTTP 
> requests.
> Sending arbitrary HTTP request headers with Flash
> =================================================
> The following is ActionScript 2.0 syntax for sending out a GET 
> request (in this example, to 
> http://www.vuln.site/some/page.cgi?p1=v1&p2=v2) with an arbitrary 
> HTTP header (Foo: Bar). This code works with Flash 7 and Flash 8 
> (probably with Flash 6 as well):
> var req:LoadVars=new LoadVars();
> req.addRequestHeader("Foo","Bar");
> req.send("http://www.vuln.site/some/page.cgi?p1=v1&p2=v2",
>          "_blank","GET");
> A similar syntax will send POST request (with the same header, to 
> the same URL, and with body a=b&c=d):
> var req:LoadVars=new LoadVars();
> req.addRequestHeader("Foo","Bar");
> req.decode("a=b&c=d");
> req.send("http://www.vuln.site/some/page.cgi?p1=v1&p2=v2",
>          "_blank","POST");
> (note: the LoadVars.decode() method was added in Flash 7, yet 
> it's probably possible to compose an arbitrary POST body without 
> it, so Flash 6 may be covered as well by this variant).
> The request is sent from the browser invoking the Flash object. 
> Any cookies the browser normally sends, will be sent in those 
> cases as well. The browser's User-Agent is sent, as well as all 
> browser standard headers. HTTPS links are supported.
> This was successfully demonstrated with Microsoft IE 6.0, 
> Microsoft IE 6.0 SP2 and FireFox, running Flash 
> and Flash
> In IE, it is possible to overwrite some "normal" browser headers 
> by simply calling addRequestHeader with the new value. This is 
> applicable to both Referer and User-Agent. In FireFox, 
> such headers, when used in addRequestHeader() will be appended to 
> the HTTP request header section.
> // One UA in IE 6.0 SP2, two UAs in FF
> req.addRequestHeader("User-Agent","Hacker/1.0");  
> // One Referer in IE 6.0 SP2, two Referers in FF
> req.addRequestHeader("Referer","http://somewhere/");
> In IE, it is also possible to overwrite some more sensitive 
> headers (e.g. Host and Content-Length) by appending colon to the 
> header name (this technique was described in [3] in the context 
> of XmlHttpRequest):
> req.addRequestHeader("Host:","foobar.site");
> This technique doesn't appear to work in FireFox 
> Note: when the target URL is in the same domain with the Flash 
> movie, LoadVars may be used to read the HTTP response data, thus 
> making LoadVars the basis for many Flash-based AJAX-like 
> frameworks (in analogy to Javascript's XmlHttpRequest object).
> The security implications
> =========================
> The ability of an attacker to force a victim's browser to send 
> HTTP requests to 3rd party sites with arbitrary HTTP request 
> headers has impact on our understanding of web application 
> security - both on assessment of security-related phenomena, and 
> on the validity of some security mechanisms.
> It is important to understand that the attacks described here are 
> (in themselves) not cross-site scripting attacks, neither are 
> they (strictly speaking) any breach of cross-domain trust in the 
> Flash object or between the Flash object and the embedding HTML 
> page. They merely make use of the fact that it's possible to send 
> requests from a Flash object to any URL, with almost any HTTP 
> headers the attacker needs. This in itself is the problem, as it 
> enables an attacker to send a link (to an HTML page embedding a 
> Flash object, or directly to a Flash object residing at the 
> attacker's website) that will cause a Flash object to be executed 
> in the victim's browser. This Flash object will send the HTTP 
> request (with HTTP headers chosen by the attacker) to a target 
> website, and this in turn will compromise the security of the 
> browser (victim).
> In other words, the implicit assumption made by many software 
> developers (and probably also by many security researchers) that 
> most HTTP headers cannot be forced to have arbitrary values by an 
> attacker who serves data to the victim browser is shown to be in 
> error in this write-up.
> Example 1 - The "Expect" header
> -------------------------------
> In [4], an injection problem was described wherein Apache 1.3.34, 
> 2.0.57 and 2.2.1 are vulnerable to injecting HTML data (including 
> malicious Javascript code) through the Expect header. In [5], 
> yours truly commented, with respect to this issue, that 
> "Regarding XSS This phenomenon is not XSS per-se. Unless someone 
> can show me how it is possible to force a browser to send the 
> Expect header to the target site". But using a Flash object, the 
> attack is trivial (the author is therefore answering his own 
> question here...). Consider a victim (browser) that clicks the 
> following link:
>   http://www.evil.site/attack.swf
> This URL represents a Flash object that runs the following 
> ActionScript code:
>   var req:LoadVars=new LoadVars();
>   req.addRequestHeader("Expect",
>                        "<script>alert('gotcha!')</script>");
>   req.send("http://www.target.site/","_blank","GET");
> This ActionScript sends a request from the victim's browser, to 
> the target website (www.target.site) with an Expect header 
> containing malicious HTML (Javascript) code. If the target 
> website runs a vulnerable version of Apache, the net result is 
> cross site scripting. So to be clear - there's a working XSS 
> attack against Apache 1.3.34, 2.0.57 and 2.2.1 (as long as the 
> client browser is IE or Firefox, and it supports Flash 6/7+). As 
> noted in [5], for Apache 2.0/2.2 the XSS response is returned by 
> the server only after the request timeout elapses (typically few 
> minutes). Please note though that a fix for the Apache server is 
> available at all 3 branches (as Apache 1.3.35, 2.0.58 and 2.2.2 
> respectively).
> Example 2 - CSRF and Referer
> ----------------------------
> CSRF (Cross Site Request Forgery) attack is in essence the 
> ability of an attacker to force a victim (browser) to effectively 
> perform an action (send HTTP request) in a target site. This 
> concept emerged several times, the first one probably on the Zope 
> mailing list (as "Client Side Trojans", [6], and another time on 
> BugTraq, under its now de-facto standard name, CSRF [7]. Both 
> references suggest, among other measures, to rely on the HTTP 
> Referer header as evidence that the browser emits the HTTP 
> request from a link originating in the website. Indeed, 
> considering the capabilities of HTML+Javascript, effectively 
> spoofing the Referer is nearly impossible (one exception is [8], 
> but it is effective only in a limited subset of scenarios; e.g. 
> it is not effective when HTTPS is used). However, as can clearly 
> be understood, with Flash this no longer holds, and Referer can 
> be spoofed for requests to HTTPS resources, all the while having 
> the browser send the site's cookies with the request. As 
> demonstrated above, both GET requests (with arbitrary host and 
> query parts) and POST requests (with arbitrary host and query 
> parts, and body in the standard Content-Type format of 
> "application/x-www-form-urlencoded") can be sent.
> Note: there are many other reasons not to rely on the Referer 
> header, and this text is by no means the first one to warn 
> against this practice.
> It should be obvious that any reasonable header (and combinations 
> thereof) can be spoofed. In IE's case, the header provided by the 
> attacker can replace the browser-provided header (e.g. Referer). 
> In Firefox's case, the Referer spoofing technique may fail 
> because Firefox adds the header at the bottom of the HTTP request 
> headers. Still, some web applications may use the last value of 
> the header, and as such be vulnerable to this technique.
> Plainly put, all this means that (reflective) cross site 
> scripting attacks that make use of HTTP request headers (e.g. 
> Referer, User-Agent, Expect, Host, Content-Type) to send the 
> payload are now possible.
> Flash 9
> =======
> Flash 9 was announced June 28th, 2006 [9] (i.e. less than a month 
> ago). In Flash 9, the techniques described above (for the 
> LoadVars class) do not work for any browser-provided header (e.g. 
> User-Agent, Host and Referer), nor probably for many "protected" 
> headers such as Content-Length. Still, headers like Expect can be 
> sent, so some attacks (e.g. Example 1 above) are still effective 
> with Flash 9.
> Limitations of the technique
> ============================
> - The URL and the body part will always be URL-encoded. That 
>   is, it is impossible (so it seems) to force SP, HT, CR and 
>   LF (and probably many other characters) to appear in their 
>   raw form in the request URL and body.
> - Only GET and POST methods can be used.
> - In IE, only one instance of each header can be sent.
> - At large, the header section cannot be completely 
>   controlled, e.g. an attacker may have problems when 
>   attempting to send special characters inside headers.
> Partial solution
> ================
> Notice the first limitation of the technique - it states that no 
> raw CR and LF can be placed in the body section. This means that 
> the technique cannot be used to send (POST) requests whose body 
> complies with the "multipart/form-data" content-type format (this 
> format uses raw CRs and LFs to mark headers and boundaries). In 
> other words, a (POST) request whose body is a valid 
> "multipart/form-data" stream is guaranteed (as far as today's 
> knowledge extends) not to be sent from a Flash player. Web 
> application authors can therefore use HTML forms whose ENCTYPE 
> attribute is set to "multipart/form-data", and enforce that the 
> submission contains a valid multipart/form-data body. Once these 
> mechanisms are in place, and a request passes through, it is 
> known not to originate from a Flash player, so the attack 
> described here is irrelevant. 
> This solution is of course intrusive - both the HTML pages and 
> the receiving scripts must be altered to use (and enforce) 
> multipart/form-data. With some web development platforms, this is 
> trivial, yet in others (e.g. raw Perl, and ASP) it is not. 
> Furthermore, in cases such as Example 1 above, the HTTP headers 
> are interpreted and used by the (Apache) web server, and the 
> control never reaches the web application layer, so in such 
> cases, this solution is not applicable.
> Future directions
> =================
> HTTP Request Splitting ([8]) and HTTP Request Smuggling ([10]) - 
> in IE + Flash 7/8 it is possible to send a Content-Length header 
> with any value. This opens up an opportunity to perform HTTP 
> Request Splitting attacks. Also, injecting Transfer-Encoding 
> header, or a second Content-Length header may open up HTTP 
> Request Smuggling. Further research is needed in order to 
> understand whether these directions lead to viable exploitation 
> techniques.
> Flash 9 - while experiments show that Flash 9 is more strict 
> concerning which headers can be specified through 
> LoadVars.addRequestHeader(), it's ActionScript 3.0 language is 
> much richer than ActionScript 2.0. As such, it may open up 
> several interesting opportunities at the HTTP level, e.g. the 
> ability to send various HTTP methods, not just GET and POST 
> (WebDAV anyone?). Flash 9 and ActionScript 3.0 should be studied 
> better in order to understand what is their potential with 
> respect to crafting HTTP requests.
> Conclusions
> ===========
> Relying on the authenticity of HTTP request headers when they are 
> sent from a browser is not a good idea. Practically every header 
> can be spoofed if the client can be forced to run a malicious 
> Flash movie, and this is probably applicable to over 80% of the 
> Internet desktops (i.e. Internet desktops running IE + Flash 
> 7/8). Consequently, the applicability of cross site scripting 
> attacks based on such headers, as well as cross site request 
> forgery attacks (against sites which protect themselves by 
> checking the Referer header) is higher than many people may 
> perceive.
> A partial solution to the latter case was suggested in the write-
> up, however it is strongly tied to the specific technology used - 
> Flash, and as such may not provide any protection against 
> variants that make use of a different technology, or against 
> developments in Flash itself. For cross-site request forgery, 
> therefore, different solutions, not relying on Referer, should be 
> considered.
> References
> ==========
> [1] "Technology Breakdown" (Adobe website)
> http://www.adobe.com/products/player_census/flashplayer/tech_breakdown.html
> [2] "Macromedia Flash Player Version Penetration" (Adobe website) 
> http://www.adobe.com/products/player_census/flashplayer/version_penetration.html
> [3] "Re: 'Exploiting the XmlHttpRequest object in IE' - paper by 
> Amit Klein" by Anonymous, BugTraq posting, September 27th, 2005
> http://www.securityfocus.com/archive/1/411823
> [4] "Unfiltered Header Injection in Apache 1.3.34/2.0.57/2.2.1" 
> by Thiago Zaninotti, BugTraq posting, May 8th, 2006
> http://www.securityfocus.com/archive/1/433280
> [5] "Re: Unfiltered Header Injection in Apache 
> 1.3.34/2.0.57/2.2.1" by Amit Klein, BugTraq posting, May 18th, 2006
> http://www.securityfocus.com/archive/1/434729
> [6] "Client Side Trojans", Zope developers mailing list, May 2000
> http://www.zope.org/Members/jim/ZopeSecurity/ClientSideTrojan
> [7] "Cross Site Request Forgeries" by Peter Watkins, BugTraq 
> posting, June 15th, 2001
> http://www.tux.org/~peterw/csrf.txt
> [8] "Exploiting the XmlHttpRequest object in IE - Referrer 
> spoofing, and a lot more..." by Amit Klein, BugTraq posting, 
> September 24th, 2005
> http://www.securityfocus.com/archive/1/411585
> [9] "Adobe Flash Player 9 Leads a New Generation of Dynamic Media 
> and Rich Internet Applications" (Adobe website), June 28th, 2006
> http://www.adobe.com/aboutadobe/pressroom/pressreleases/200606/062806Flash9.html
> [10] "HTTP Request Smuggling" by Chaim Linhart, Amit Klein, Ronen 
> Heled and Steve Orrin, June 6th, 2005
> http://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf
> ----------------------------------------------------------------------------
> The Web Security Mailing List: 
> http://www.webappsec.org/lists/websecurity/
> The Web Security Mailing List Archives: 
> http://www.webappsec.org/lists/websecurity/archive/
> http://www.webappsec.org/rss/websecurity.rss [RSS Feed]

The Web Security Mailing List: 

The Web Security Mailing List Archives: 
http://www.webappsec.org/rss/websecurity.rss [RSS Feed]

More information about the websecurity mailing list