Forged POST requests can be constructed by untrusted websites by creating a form and posting it to the target site. However, the raw contents of this POST will be encoded by the browser to be in the format:
param1=value1¶m2=value2
Is it possible for untrusted websites to construct forged POSTs which contain arbitrary raw content -- such as stringified JSON?
{param1: value1, param2: value2}
Put another way: Can websites cause the browser to POST arbitrary content to third-party domains?
The POST body of an HTML form’s request is always either application/x-www-form-urlencoded, multipart/form-data, or text/plain as these reflect the valid values for the enctype
attribute. Especially text/plain
one can be used to form valid JSON data. So form-based CSRF can be used here, however, it requires the server to accept it as text/plain
.
Additionally, XHR-based CSRF can be used as the XMLHttpRequest API allows so send arbitrary POST data. The only remaining obstacle with this is the Same-Origin Policy: Only if both have the same origin or your server supports Cross-Origin Request Sharing and allows resource sharing, such valid POST requests can be forged.
Yes!, a POST request is nothing more than text with a specific format sent to a web server. You can use IE or Chrome developer tools to look at what each requests looks like.
So yes, you can create a forged POST request and change whatever you want, however if the request is not well-formed most web servers will reject it.
http://tools.ietf.org/html/rfc2616
The client side code of a web site would have difficulties to forge a request like that, but the server side code could very easily do that.
As your web site can't tell if the request comes from a browser or a server that behaves just like a browser, the limitations in the browser is no protection.
You can create valid JSON via a regular form post. It's just a matter of creatively naming the form parameters. In particular, parameter names can contain quotes.
http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html
In the case of pure HTML forms, yes it will always be encoded according to the spec. But there are other encoding schemes such as MIME multipart. There is also the question of Javascript and XMLHttpRequest. Encoding is specifically mentioned in only one case. This strongly implies that there is no encoding applied in the other cases.