Skip to main content
Inspiring
April 11, 2022
Question

verifyCSRFToken fails randomly

  • April 11, 2022
  • 1 reply
  • 955 views

Environment: CF2016 + patch17

OS: Windows

Session Enabled and hosted via Elasticache (Redis)

Multi-instance environment

Load: A LOT

 

 

Given the two functions:

/**
 * Method used to create a CSRF token, mainly used for login forms - Returns string
 *
 * tokenKey - optional, string. Unique key. Must also be used for decoding the token
 * forceNew - optional, boolean. Defualt to true. Will create new token each time the method is called
 **/
public string function generateCSRFToken( string tokenKey='some-special-key', boolean forceNew=true ){
	return CSRFGenerateToken(  arguments.tokenKey, arguments.forceNew );
}

/**
 * Method used to verify a CSRF token, mainly used for login forms - Returns string
 *
 * token - required, string. The token to be verified
 * tokenkey - optional, string. Defualt to true. Will create new token each time the method is called
 **/
public boolean function verifyCSRFToken( required string token, string tokenKey='some-special-key' ){
	return CSRFVerifyToken( arguments.token, arguments.tokenKey ) ? true : false;
}

 

The way I understood the CSRFGenerateToken() function, it creates a token and sticks it into the session. Given that our multi-instance environment is using the same Elasticache service (to prevent session duplication) and so the session is shared on all instances, I would assume that the CSRFVerifyToken() would not have an issue verifying the token (presummably that is in the session). For some very ODD reason, it fails for random users - I don't have any debug information other than when the CSRFVerifyToken() function is called, it returns false. 

 

Thoughts?

    This topic has been closed for replies.

    1 reply

    BKBK
    Community Expert
    Community Expert
    April 12, 2022

    @--jojo-- , I think the way you understand CSRFGenerateToken() is correct. But I also think the design with the two custom functions isn't optimal.

     

    Under the covers, ColdFusion may non-transparently change sessions. Which shouldn't be a bother at all. Requests will then be handled seamlessly by the next session.

     

    However, with your design, a situation could arise where the session change occurs between the call generateCSRFToken() and the call verifyCSRFToken(). By virtue of

     

    forceNew=true

     

    the following sequence of events might happen:

    1. Session S: the caller of verifyCSRFToken() obtains a token Ts with which to call the function;
    2. Session changes from S to S+1;
    3. The caller of generateCSRFToken() calls the function, generating a new token Ts+1;
    4. The caller of verifyCSRFToken() calls the function, passing it the token Ts.

     

    A possible solution:

     

    forceNew=false

     

    --jojo--Author
    Inspiring
    April 12, 2022

    Thanks @BKBK What you suggested makes sense - Will definitely try what you've suggested and hopefully will solve our issue.  Will report back.