<img src="<https://vulnerable-website.com/email/[email protected]>">
The most robust way to defend against CSRF attacks is to include a CSRF token within relevant requests. The token should be:
CSRF tokens can prevent CSRF attacks by making it impossible for an attacker to construct a fully valid HTTP request suitable for feeding to a victim user. Since the attacker cannot determine or predict the value of a user's CSRF token, they cannot construct a request with all the parameters that are necessary for the application to honor the request.
You should use a cryptographic strength pseudo-random number generator (PRNG), seeded with the timestamp when it was created plus a static secret.
If you need further assurance beyond the strength of the PRNG, you can generate individual tokens by concatenating its output with some user-specific entropy and take a strong hash of the whole structure. This presents an additional barrier to an attacker who attempts to analyze the tokens based on a sample that are issued to them.
<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />
For additional safety, the field containing the CSRF token should be placed as early as possible within the HTML document, ideally before any non-hidden input fields and before any locations where user-controllable data is embedded within the HTML. This mitigates against various techniques in which an attacker can use crafted data to manipulate the HTML document and capture parts of its contents.
An alternative approach, of placing the token into the URL query string, is somewhat less safe because the query string:
Is logged in various locations on the client and server side;
Is liable to be transmitted to third parties within the HTTP Referer header; and
can be displayed on-screen within the user's browser.
Some applications transmit CSRF tokens within a custom request header. This presents a further defense against an attacker who manages to predict or capture another user's token, because browsers do not normally allow custom headers to be sent cross-domain. However, the approach limits the application to making CSRF-protected requests using XHR (as opposed to HTML forms) and might be deemed over-complicated for many situations.
CSRF tokens should not be transmitted within cookies.
The SameSite
attribute can be used to control whether and how cookies are submitted in cross-site requests. By setting the attribute on session cookies, an application can prevent the
default browser behavior of automatically adding cookies to requests regardless of where they originate.
SameSite
attribute is added to the Set-Cookie
response header when the server issues a cookie, and the attribute can be given two values, Strict
or Lax
. For example:
SetCookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Strict;
SetCookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Lax;
SameSite
attribute is set to Strict
, then the browser will not include the cookie in any requests that originate from another site. This is the most defensive option, but it can impair the user experience, because if a logged-in user follows a third-party link to a site, then they will appear not to be logged in, and will need to log in again before interacting with the site in the normal way.SameSite
attribute is set to Lax
, then the browser will include the cookie in requests that originate from another site but only if two conditions are met:
SameSite
cookies in Lax
mode does then provide a partial defense against CSRF attacks, because user actions that are targets for CSRF attacks are often implemented using
the POST method. Two important caveats here are: