Sending multipart/form-data requests from Flash (with arbitrary headers)
Hello lists,
In my original "Forging HTTP request headers with Flash" paper
(http://www.securityfocus.com/archive/1/441014), I mentioned forcing
multipart/form-data
input format to ensure that Flash's LoadVars isn't used to forge the request.
However, there's a work-around for the attacker - using Flash's XML object. The
attacker
can forge almost any practical input for multipart/form-data (as long as it's
part of a
well-formed XML document):
var req:XML=new XML("<foo>\r\n--bar\r\nContent-Disposition: form-data;
name=field1\r\n\r\ndata1\r\n--bar\r\nContent-Disposition: form-data;
name=field2\r\n\r\ndata2\r\n--bar--\r\n</foo>");
req.addRequestHeader("Content-Type","multipart/form-data; boundary=\"bar\"");
req.addRequestHeader("Referer","http://some.site/");
req.addRequestHeader("Expect","something");
req.send("http://www.vuln.site/path/to/script.cgi","_blank");
It seems that the capabilities of the XML object (XML.send), in terms of
forging HTTP
request headers, are similar to those of LoadVars (LoadVars.send). The above
code works
well in IE 6.0 (Flash 7 and 8).
The reader may note that there's a bit of data in the body before the first
MIME part
(that's the <foo> start-element) as well as a bit of data after the last MIME
part
(</foo>). As it happens, the multipart Content-Type allows such "preamble"
(data before the
first multipart boundary delimiter) and "epilogue" (data after the last
multipart boundary
delimiter) - see RFC 2046 section 5.1.1, and indeed application engines (e.g.
PHP) silently
ignore those parts.
One shortcoming of the technique is that it cannot express all possible data.
This is due
to the fact that the XML object stores its XML data in an XML tree, and then
serializes
this tree to an XML document upon invocation of the send() method. This
serialization
doesn't duplicate the exact XML input (byte-wise, although logically the same
tree would
result), and it also guarantees that the serialized data is a well formed XML
document. For
example, any double quote marks will be converted to their XML entity
representation
("), likewise for several other symbols. Theoretically, this means that
it's still
possible to distinguish a Flash submission from a browser submission, by
forcing data with
those symbols to be sent, e.g. using hidden fields with those values. But I
wouldn't
recommend this practice as it doesn't sound like "The Right Thing" - it's way
too
implementation specific.
Bottom line: multipart/form-data submissions can be forged almost completely,
headers and
all, using Flash 7/8 (in IE 6.0).
-Amit