0

I know how actually CSRF works, it usually stores the random text in session and will have same on the HTML form in hidden token CSRF field. When user submits the form, the HTML form token in matched with session CSRF and validate respectively.

The doubt is if I refresh the page, new CSRF token will be generated and will be valid only once till the next refresh. In this case if I open the same form multiple time in new tabs and submit the subsequent forms how would the framework or anyone store the token in session and validate it. Will it be storing the latest token or will store all the new tokens generated in the form of array and after validating the token it will remove the token from session.

I am not able to get how multiple tokens for the same user will be handled when the HTML form opened in multiple tabs and submitted one after the other.

I am dumping the session in the controller but not able to see all the tokens over there as per my assumptions.

Can anyone help me understand how it handles.

Channaveer Hakari
  • 2,769
  • 3
  • 34
  • 45
  • Usually there shuld be 1 token for each
    submitted. And a corresponding Check for each. So, there will only be 1 token active at a given time. Otherwise it does not work.
    – halojoy Dec 29 '17 at 07:55
  • In one
    there will be one
    token generated and at same time one $_SESSION value. When
    is submitted you test the posted token against $_session value .. they should match
    – halojoy Dec 29 '17 at 07:58
  • @halojoy If that's the case then how will my form work. Think that I have **product** page and I want to add multiple products. So I open the form in multiple tabs (say tab1, tab2, tab3, tab4 all have the product form page). If i fill the first tab1 then it will work fine and even it works for the subsequent tabs. **But as per your saying the other tabs wont work as the token will be regenerated and the old one will be deleted.** – Channaveer Hakari Dec 29 '17 at 07:59
  • When
    is executed/displayed the token is created. Then after submission it is tested. So in any tab you can check the token. I think.
    – halojoy Dec 29 '17 at 08:04
  • Ya token will be shown different in different tab. How would the framework store the token in session, in the form of array or how. – Channaveer Hakari Dec 29 '17 at 08:27
  • Usually $_SESSION['one_key'] – halojoy Dec 29 '17 at 08:44
  • If thats the case then the form opened in tab2, tab3 and so on must throw me an error but its not doing that – Channaveer Hakari Dec 29 '17 at 08:45

2 Answers2

0

I use https://github.com/Vundo/CSRF
It is so simple it can get

session_start();
<form method="post" accept-charset="UTF-8">
    <input type="submit" value="<?php echo SUBMIT ?>">
    <input type="hidden" name="_token" value="<?php echo CSRF::generate() ?>">
</form>

And the receiving page after submission:

$session_start();
if(isset($_POST['xxxxxxx'])) {
    if(!CSRF::check($_POST['_token'])){
        exit('Wrong Token!');
    }
halojoy
  • 225
  • 2
  • 7
  • Thanks for the link. But it doesnt explain me what I am looking for. Can you explain for subsequent form in different tabs opened and once submitted individually how will that be taken care. How it actually implement that – Channaveer Hakari Dec 29 '17 at 08:55
  • As the token will be overridden. Do you think the form opened in different tab will work. If so can you please explain it to me. – Channaveer Hakari Dec 29 '17 at 08:57
  • You can check the result in any or all of where it opens after submit. The toke will be the same for all, as it is only created once in the original page. – halojoy Dec 29 '17 at 11:45
0

In CodeIgniter every time you open a form, or in your case, a new tab (you mean browser tab right?) you get a token. This token is stored, and using form_open outputted to a hidden input. On submit, it is checks to make sure the stored token and the form token are the same. It is a very simple process much like that which halojoy outlined.

In the comments you stated that despite having multiple forms open in different tabs, you are still able to submit the forms without a CSRF error. This is most likely due to a configuration setting $config['csrf_regenerate'] = FALSE;

Tokens may be either regenerated on every submission (default) or kept the same throughout the life of the CSRF cookie. The default regeneration of tokens provides stricter security, but may result in usability concerns as other tokens become invalid (back/forward navigation, multiple tabs/windows, asynchronous actions, etc). You may alter this behavior by editing the following config parameter

So basically if you had regenerate enabled the cookie gets regenerated every time you open a new tab with a form. Thus, whichever form was opened last would be the last one to set and have the only valid CSRF token.

Example:

  • Tab 1: form sets token as 123 and gets token as 123 in hidden field. (Opens tab 2)
  • Tab 2: form in tab 1 still has token as 123 in hidden field but now token is 456 (regenerated) and hidden field is 456 (valid)

Form in Tab 1 on submit will fail, while form in tab 2 will succeed.

Alex
  • 9,215
  • 8
  • 39
  • 82
  • Think that I want to implement the same in any of my plain PHP project then would I be doing the same. If the user opens form in multiple tabs then I must restrict him to open only one form instead of multiple – Channaveer Hakari Dec 29 '17 at 10:15
  • I would suggest against this. I can't think of a way to limit that kind of user interaction (you can't easily and reliably control what the user does with their browser). Further if you plan to use AJAX this quickly falls apart even if you add the token to ajax setup. I keep regenerate off in my project. – Alex Dec 29 '17 at 10:20
  • The csrf hash won't change until a POST request is made to the server. Multiple tabs (with forms) can be opened and each will have the same hash value. However, if `$config['csrf_regenerate'] = TRUE;` when a POST request is made the hash is regenerated and previously opened tabs will now fail the verify test. Other than that @Alex your answer and comment is spot on. – DFriend Dec 29 '17 at 16:55