Say the attacker owns a domain, attacker.com
. Attacker wants to create a webpage on it to make a CSRF attack toward the victim.com
server. The targeted page is victim.com/target.php
which only accepts POST request, with a specific Accept
header of, say, application/x-foo
.
With such setup, I couldn't find a way for the attacker to craft a CSRF page:
- If attacker does a
<form action="victim.com/target.php" method="POST">
then I see no way for the attacker to set theAccept
header and so thetarget.php
file won't do any action - If the attacker makes a
const xhr = new XMLHttpRequest(); xhr.setRequestHeader('Accept', 'application/x-foo');
then the browser preflights a CORS requestOPTIONS
to thetarget.php
which responds nothing (because it's notPOST
) and so the browser won't make the CSRF request - The attacker cannot use a URL-based CSRF (like
victim.com/target.php?param=xyz
) becausse it's not POST either - Attacker does not own the
victim.com
server so they cannot put a non-cross-domain XHR inb there
Even tho I cannot find an exploit, it feels very unlikely to me that a simple check such as ($_SERVER['HTTP_ACCEPT'] !== 'application/x-foo')
in the victim's webpage is enough to prevent any CSRF attack... still, I see no exploit?!
It seems very close to OWASP's custom header CSRF prevention but Accept is not custom: does this change a thing?
Accept
in some browsers in the documentation and make sure you use a browser which is not affected by these restrictions.