I am playing around with a test application which accepts JSON requests and response is also JSON. I am trying to do a CSRF for a transaction which accepts only JSON data with POST method in request. Application throws an error if URL is requested using get method (e.g. in <script src=).

Also for the attack to be meaningful i.e. transaction to go through, I have to send the data in the request. If I create my own page and send the JSON requests, cookies do not travel and hence server returning an unauthenticated error message.

There are no random tokens in original request by server.

I was wondering is there any way to carry out a successful CSRF attack in this scenario.

2 Answers 2


You must at the very least check for Content-Type: application/json on the request.

It's not possible to get a POSTed <form> to submit a request with Content-Type: application/json. But you can submit a form with a valid JSON structure in the body as enctype="text/plain".

It's not possible to do a cross-origin (CORS) XMLHttpRequest POST with Content-Type: application/json against a non-cross-origin-aware server because this will cause a ‘pre-flighting’ HTTP OPTIONS request to approve it first. But you can send a cross-origin XMLHttpRequest POST withCredentials if it is text/plain.

So even with application/json checking, you can get pretty close to XSRF, if not completely there. And the behaviours you're relying on to make that secure are somewhat obscure, and still in Working Draft stage; they are not hard-and-fast guarantees for the future of the web.

These might break, for example if a new JSON enctype were added to forms in a future HTML version. (WHATWG added the text/plain enctype to HTML5 and originally tried also to add text/xml, so it is not out of the question that this might happen.) You increase the risk of compromise from smaller, subtler browser and plugin bugs in CORS implementation.

So whilst you can probably get away with it for now, I absolutely wouldn't recommend going forward without a proper anti-XSRF token system.

  • 2
    It's good to add that the CSRF attacks will be blind (i.e. attacker won't get access to the response). Commented Dec 30, 2011 at 12:27
  • 4
    +1 I would also say that relying upon any http header is a weaker form of protection because of HTTP Request Splitting (as in CRLF injection in the client). Using a token is still the recommended method of defense for most applications.
    – rook
    Commented Dec 30, 2011 at 16:22
  • 10
    W3C HTML JSON form submission was published. w3.org/TR/html-json-forms Commented Jun 9, 2014 at 16:51
  • 3
    A little update to this - it is possible now to send the application/json POSTs cross domain with navigator.sendBeacon API - developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon Commented Jun 5, 2015 at 13:01
  • 1
    @kravietz You've done something wrong. Chrome 57 either re-introduced this bug or it was never fixed because I've managed to just exploit using exactly this. Use something like this: var blob= new Blob([JSON.stringify(YOUR JSON)], {type : 'application/json; charset=UTF-8'}); to generate a JSON blob and it'll send perfectly. CSRF in seconds!
    – Allison
    Commented Apr 21, 2017 at 4:21

This is exploitable using Flash, according to https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_Flash

The ability to make cookie-bearing cross-domain HTTP GET and POST requests via the browser stack, with fewer constraints than typically seen elsewhere in browsers. This is achieved through the URLRequest API. The functionality, most notably, includes the ability to specify arbitrary Content-Type values, and to send binary payloads.

I haven't tested it myself but it sounds plausible.

Update: It looks like the latest Flash releases no longer allow any cross-domain requests by default, rendering this unexploitable.

Update #2: however there's a longstanding vulnerability in flash's handling of 307 redirects which means this is still exploitable

  • May you detail second update please ? Commented Feb 4, 2018 at 3:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .