CSRF Tokens forceNew=false only works in short timespans

Description

Possibly related to https://luceeserver.atlassian.net/browse/LDEV-784 (though this ticket does not use session clustering - just a single Redis cache)

Assumption: When forceNew is false, csrfGenerateToken(key, false) should generate the same value for as long as the underlying session persists, given the same input key. For example, if your session timeout is six hours, `csrfGenerateToken( 'foo', false )` should produce the same result now and five hours from now.

Issue: This works as expected unless Redis is used for session storage. A new key is generated even with `forceNew=false`, so verification of CSRF in Redis session storage fails even though the key is still in Redis. and the underlying session scope is the same.

The attached test case launches a simple redis container and a Commandbox/Lucee container running 5.3 (currently 5.3.2.38-SNAPSHOT). It needs to have the Lucee Redis extension installed as I couldn't do this automatically without making my own Docker image and didn't want to be asking people to run unverified Docker images, so before you access the CF container on port 8080, go to Lucee admin, select 'pre-release' and install the Redis extension.

The test takes a static key based on a text seed and generates a csrf token using that as the key. Since the text portion is static, the same key should be "valid" until the underlying session expires or the key is manually removed. Session timeouts are set to one hour for the application, but the Lucee redis driver actually doesn't care about that and uses the TTL from the cache connection for expiration. That is set to 3 hours.

On every request, the page generates a token value using the same seed (and the forceNew = false argument in csrfGenerateToken so that it doesn't make a new token if one already exists). Per the docs:
https://docs.lucee.org/reference/functions/csrfgeneratetoken.html

The test page stashes the resulting token into both the application and session scope if it doesn't find it in both scopes. This is so we can compare the values regardless of storage medium. It doesn't make a difference - the issue is in the generation function's check to see if a token already exists. This points to the `csrfGenerateToken()` function rather than any other reference to the relevant values as the culprit.

Expected Result: The page should look something like this on every request:

CSRF Token Testing This page genearates a CSRF token with a static text seed. In theory, the token should be the same unles the underlying session expires. let's verify the application tokens we have so far: Application Token hak1y29q8vg0vjpgksa4343wc5nen139wijvtwg3: true now let's verify the session tokens we have so far: Session Token hak1y29q8vg0vjpgksa4343wc5nen139wijvtwg3: true

Result: It works as expected unless you leave it alone for 10-15 minutes without making a request. Then it generates a new token even though the seed hasn't changed:

CSRF Token Testing This page genearates a CSRF token with a static text seed. In theory, the token should be the same unles the underlying session expires. Did not find 1l207g456p1q21qr63brwhk9koj0pdg6gda5vvom in our application-stored token list. Adding it. Did not find 1l207g456p1q21qr63brwhk9koj0pdg6gda5vvom in our session-stored token list. Adding it. let's verify the application tokens we have so far: Application Token hak1y29q8vg0vjpgksa4343wc5nen139wijvtwg3: false Application Token 1l207g456p1q21qr63brwhk9koj0pdg6gda5vvom: true now let's verify the session tokens we have so far: Session Token hak1y29q8vg0vjpgksa4343wc5nen139wijvtwg3: false Session Token 1l207g456p1q21qr63brwhk9koj0pdg6gda5vvom: true

Instructions:

  • unzip file

  • docker-compose up (and wait a little while for it to download the latest Lucee snapshot of 5.3 – though this problem likely exists in 5.2 as well)

  • localhost:8080/lucee/admin/server.cfm (password: commandbox) --> extensions --> select pre-releases --> install Redis extension

  • navigate to localhost:8080/index.cfm

Environment

Docker / Commandbox / OpenJDK 8

Attachments

1
  • 18 Jan 2019, 06:58 pm

Activity

Show:

Pothys - MitrahSoft 5 February 2019 at 15:16

I've checked this ticket with the reporter's test file in both Docker & Commandbox. If the page get leave alone for 10-15 minutes without making a request. Then it generates a new token as per the result posted like above.

will decide about this issue.

Details

Assignee

Reporter

Priority

Labels

New Issue warning screen

Before you create a new Issue, please post to the mailing list first https://dev.lucee.org

Once the issue has been verified, one of the Lucee team will ask you to file an issue

Affects versions

Created 18 January 2019 at 18:53
Updated 19 May 2021 at 11:24

Flag notifications