Csrf Token, Changing User, (In)Security And Data Consistency

I encountered an issue of data inconsistency which is potentially a security issue.

Here is what happened:

  • A user (UserA) is logged in in on tab of the navigator. This tab sends POST requests to the server.

  • In another tab of the navigator, another user is logged in. In my case this is done through an url generated from the backoffice which acts as a login process.

  • After the other user (UserB) is logged in in the second tab, the first tab sends a post request to the server. The server validates this request as a request of the second user because of session/cookie information, and validates the CSRF token because the CSRF token did not change.

Analysis:

  • Changing the user does not change the CSRF token.

  • The post operation of UserA in the first tab is validated because the CSRF token is ok, and is attributed to UserB because the Session/Cookie says it is UserB.

  • The session does not seem to be detroyed when changing a user - it may be destroyed when the user logs out.

  • Calling ‘login’ does not destroy the session. I haven’t checked if a session is tab specific - I suppose it is not.

My current solution/workaround is to force a change of the CSRF token when the user changes. So my extension of the CWebUser class now has the following code:





    protected function changeIdentity($id, $name, $states) {

        parent::changeIdentity($id, $name, $states);

        $request=Yii::app()->getRequest();

        if($request->enableCsrfValidation) {

            $request->getCookies()->remove($request->csrfTokenName);

        }

    }



I do not particularly like this code because it supposes the CHttpRequest works a certain way, but I did not see a better way to do this for the moment.

Identifying this explains some of the strange behaviors I have seen in the past in my web application. I am happy that I could finally pin it down.