New CSRF token per request or NOT?

后端 未结 5 1297
不知归路
不知归路 2020-11-29 00:11

So I am reading around and was really confused about having a CSRF token, whetever I should generate a new token per each request, or just per hour or something?

         


        
5条回答
  •  余生分开走
    2020-11-29 01:03

    If you do it per form request - then you basically remove the ability for CSRF attacks to occur & you can solve another common issue: multiple form submission

    In simple terms - your application will only accept form input if the user ASKED for the form prior to the submission.

    Normal scenario: User A goes to your website, and asks for Form A, is given Form A plus a unique code for Form A. When the user submits Form A, he/she must include the unique code which was only for Form A.

    CSRF Attack scenario: User A goes to your website, and asks for Form A. Meanwhile they visit another "bad" site, which attempts a CSRF attack on them, getting them to submit for a fake Form B.

    But your website knows that User A never asked for Form B - and therefore even though they have the unique code for Form A, Form B will be rejected, because they dont have a Form B unique Code, only a Form A code. Your user is safe, and you can sleep easy at night.

    But if you do it as a generic token, lasting for an hour (like you posted above) - then the attack above might work, in which case you've not achieved much with your CSRF protection. This is because the application does not know that form B was never asked for in the first place. It is a generic token. The WHOLE POINT of CSRF prevention is to make each form token unique to that form

    Edit: because you asked for more information: 1 - you dont have to do it per form request, you can do it per hour/session etc. The point is a secret value that is given to the user, and resubmiited on the return. This value is not known by another website, and thus cannot submit a false form.

    So you either generate the token per request, or per session:

    // Before rendering the page:
    $data['my_token'] = md5(uniqid(rand(), true));
    $_SESSION['my_token'] = $data['my_token'];
    
    // During page rendering:
    
    
    // After they click submit, when checking form:
    if ($_POST['my_token'] === $_SESSION['my_token'])
    {
            // was ok
    }
    else
    {
              // was bad!!!
    }
    

    and because it is "per form" - you wont get double form submissions - because you can wipe the token after the first form submission!

提交回复
热议问题