First there came XMLHttpRequest, and then came Flash. This week, Alex released some great research demonstrating a new technique for spoofing browser HTTP headers.
The original problem with Flash was that it could be used to spoof any HTTP header within the browser of a user who invoked the Flash object. The fix that was applied to Flash did not make the problem go away altogether. It prevented Flash being used to spoof certain built-in browser headers, such as Referer and User-Agent. However, if a vulnerable page echoes the contents of all the headers that it received (as often happens in diagnostic error messages), then Flash is still a viable delivery mechanism for a reflected XSS attack.
What Alex has noticed is that many programming languages use underscores instead of hyphens when naming a header whose value they wish to access. For example, in PHP the following will retrieve the value of the User-Agent header:
$_SERVER['HTTP_USER_AGENT']
Predictably enough, a Flash object can be used to spoof a header containing the non-standard name:
req.addRequestHeader("User_Agent", "<script>alert('xss')</script>");
This is not blocked by the fix to the original problem, and yet in many languages (most notably PHP, Perl, Ruby and ColdFusion) the application will process the attacker's payload instead of the browser's built-in header. Very nice.
Alex also discusses some other attacks, which are well worth a read.
There is an important lesson in all of this, beyond the detail of the actual attack. The subject of request header spoofing arises in all kinds of situations, including XSS, XSRF and DNS pinning. Some people do not realise there is a problem at all, and many others think it has gone away through fixes to Flash and other client-side technologies. Even if the new hole is ultimately plugged, I'd bet that another one will be found soon enough. But regardless of that, we should in general make the working assumption that a malicious web site can spoof any request header of a user who accesses that site. If your application contains XSS when echoing request headers, then fix the bug. If your application trusts request headers when defending against other attacks, then find a more robust defence, before someone else finds a way to bypass it.