Fixed
Details
Details
Assignee
Michael Offner
Michael OffnerReporter
Dominic Watson
Dominic WatsonPriority
Labels
Fix versions
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
Created 17 February 2016 at 12:29
Updated 27 April 2021 at 09:45
Resolved 21 November 2016 at 22:37
It is possible to control what CFML session tokens a user will have by sending them to a link that contains a CFID of your choosing, so long as it fits the UUID pattern.
This means I can send a user to a URL, wait for them to login and then visit that URL myself in order to be logged in as that user (better description here: https://www.petefreitag.com/item/815.cfm)
What I believe to be happening is:
1. Original request comes in with CFID=myhackedvalue
2. no session exists with that CFID
3. Lucee creates a new session using the passed CFID
Instead of 3. I believe that Lucee should be generating a new CFID so that attackers cannot simply define a session with a CFID of their choosing.
Using j2ee sessions does not suffer from this problem.
Workaround 1
One workaround is to use SessionRotate() in OnSessionStart() in your Application.cfc:
component { //... function onSessionStart() { SessionRotate(); } }
That's pretty brutal, but will ensure that you can never dictate the session tokens that are used for your session.
Workaround 1a
There's a small issue with the workaround above, the CFID and CFTOKEN cookies will be set twice, once with the original tokens (which may be passed in the URL), and again with the new ones. The following will get around that but might not be quite so comfortable:
component { //... function onSessionStart() { _removeSessionCookies(); SessionRotate(); } // ... private void function _removeSessionCookies() { var pc = getPageContext(); var resp = pc.getResponse(); var allCookies = resp.getHeaders( "Set-Cookie" ); var cleanedCookies = []; for( var i=1; i <= ArrayLen( allCookies ); i++ ) { var cooky = allCookies[ i ]; if ( !ReFindNoCase( "^(CFID|CFTOKEN|JSESSIONID|SESSIONID)=", cooky ) ) { cleanedCookies.append( cooky ); } } pc.setHeader( "Set-Cookie", "" ); for( var cooky in cleanedCookies ) { resp.addHeader( "Set-Cookie", cooky ); } } }