How to effectively prevent fake site usage requests (CSRFs) in PHP

I am trying to prevent CSRF in as follows:

  • A $_SESSION['token'] is created at the beginning of each page. I already know that using $_COOKIES completely wrong, as they are automatically sent for every request.

  • The following input is added to each <form> : <input type="hidden" name="t" value="<?php echo '$_SESSION['token']; ?>"> .

  • $_SESSION['token']; checked with $_POST['t']

Now I have a few small questions:

  • Is this a good way to prevent CSRF? If not, explain.
  • When another page also opens, which sets the same $_SESSION variable, the previous (still open) page becomes invalid, how to prevent this?
  • For forms, this method is clear, but how to handle normal links? Do I need to add a token to each link?

Thank you in advance.

+6
source share
1 answer

Is this a good way to prevent CSRF?

Yes. This is to force the client to execute a GET on the form before they can make a POST for your form handler. This prevents the use of CSRF in modern browsers, since browsers prevent client-side Javascript in order to execute an XHR GET request to a foreign domain, so the third-party cannot mimic your form on your site and successfully receive a valid token for submission.

When another page opens that sets the same $ _SESSION variable, the previous (still open) page becomes invalid, how to prevent this?

Allow multiple tokens to be valid at the same time, storing an array of valid tokens in the session. Alternatively, do not save tokens at all and use a token signature scheme. I intervened and explained that here . Alternative 2: just use one token for the entire session, without invalid tokens. (tell me about the @SilverlightFox hat in the comments)

For forms, this method is clear, but how to handle normal links? Do I need to add a token to each link?

No. You only need to protect POST requests, since presumably only POST requests can modify sensitive data (wink nudge nudge, you adhere to REST agreements, right ?!) and XHR GET requests are already blocked by the browser side.

+5
source

All Articles