I have created a page to attack a CSRF unprotected endpoint. This endpoint accepts only JSON as payload, so I have used fetch with credentials: "include" properties. The page run locally using file:// protocol.

      fetch(vulnerableEndpoint, {
        method: "POST",
        credentials: "include",
        body: JSON.stringify(myPayload),
        redirect: "follow",

CORS policies should prevent the browser calling another domain with credentials. However using Chrome :

  • In network tab :
Name Status Type Initiator Size Time
endpoint CORS error fetch xxxxx 0 B 235 ms
  • When I click to see item details
Request URL vulnerable-website/endpoint
Request Method POST
Status Code 200
Referrer Policy strict-origin-when-cross-origin

And actually my request is sent and the remote server handle it as a legit request. Access-Control-Allow-Origin is not set in response header so I guess it use default value.

I know CORS is not a defense again CSRF.

I have read OWASP guidelines : https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html

However why my request is sent by Chrome ? It seems to be a security issue.

I have done the same with Firefox and firefox block the request and the response is flagged as a 403 one.

I use Chrome v114.0.5735.134

1 Answer 1


The Fetch specication permits “simple requests” that are equivalent to form submissions. This is the case here: Your POST request does exactly the same as a form with method="post" and action="vulnerable-website/endpoint", so it wouldn't make sense to block it while allowing the same request to be made with a form submission.

Only specific requests trigger a CORS preflight and will be blocked if the server doesn't provide the right Access-Control headers.

  • Okay, that's why using custom header could mitigate CSRF , on endpoint which expects to be called through XHR only, without having to generate and check a token validity as OWASP mentionned. It makes senses now Jun 14, 2023 at 13:16
  • Concise and accurate answer; upvoted. One nit-pick: the Fetch API actually introduced ways to send simple requests that are not possible via a form submission; for instance, a HEAD request.
    – jub0bs
    Aug 29, 2023 at 19:37

You must log in to answer this question.

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