Note: This blog post is from 2013. Some content, links and indeed comments from others may be outdated--though not necessarily. Corrections are welcome, in the comments. I may revise the content if necessary.This topic came up on a discussion list, in the context of a larger thread, and I wanted to share here what I said there.
As an update since I first wrote this, it turns out this issue may or may not affect you depending on a couple of variables, which I will discuss, with a prefix of "update:" below. But don't dismiss this thinking you are not affected. I would propose that still far more CF servers may be exposed than not, as I will explain.
The CF Admin has (for several releases) offered an option called, "Use UUID for cftoken" (in the "Settings" section), and it's been intended as a security measure. Its purpose is to cause CF to use a UUID value (a long, complex string of numbers and letters) for the CFTOKEN cookie (and session variable) that CF generates, versus what used to be a simple, 8-digit value. This cookie, along with the simpler and incrementing CFID, is used to connect users to the session and/or client scope values created for that user in CF code.
Some may be surprised to learn, though, that while this setting DOES cause CF to *create* such UUID-formatted CFTOKEN values for requests that do not already present a CFTOKEN cookie, it does NOT necessarily cause CF to block any continued use of such simple, 8-digit cftoken cookies.
In other words, browsers which had visited your site before you turned on "use uuid for cftoken" would still send the 8 character cftoken they already had, not a uuid, and that could be accepted as valid by CF, even with that setting on, under certain conditions. (And the user will not be sent any new cftoken cookie in a UUID format, in CF's response, in those conditions.)
There's good and bad news related to this fact, which I will elaborate on below.
Update: Since writing this entry, I learned of a couple of factors that influence if and when this is a problem.
- It turns out that if you are using CF10, or CF9 or 8 with the "session fixation" hotfix (APSB11-04), then the problem only happens until you restart CF. The Admin does not currently warn you of this, so beware that you will have the exposure below until you do restart. (If you have added one of the later security hotfixes or cumulative hotfixes that came out since then, then you have gotten the fix.) This fix causes CF to create a new UUID-based CFTOKEN, if you turn on this feature at least (and after a restart) when a browser presents a previously created 8-digit cftoken.
- On the other hand, even if you are running CF 10, or running 8 or 9 and HAVE applied that hotfix, note that if you TURN OFF that fixation protection (by adding the -Dcoldfusion.session.protectfixation=false value to your jvm.config, as discussed in that technote), then you are back to the state that I discuss below.
- And of course, if you are on CF 8 or 9 and have NOT yet applied that APSB11-04 hotfix (or a later cumulative one that includes it), then you are indeed still vulnerable.
So that leaves still many people who could be affected by this. Even if it seems you may not be, you may want to continue reading this entry to understand what the issue is about, for you and others who may be impacted by it.
The good news: users can still access their session/client scope data
So the good news in this behavior is that users who had been to your site before the change was made would again continue to use the cfid/cftoken pair they were previously sent, and this would be needed in order to connect their browser to any existing session or client variables (client repository records) which may have been created for their given cfid/cftoken pair before you made the Admin change.
The bad news: bad guys could still try to hijack sessions and client variables
The bad news is that since the simple cftoken values are still acknowledged after the change, it means that while good guys (users) can still use them to access data that may exist for them on the server, it also means that bad guys could still try to "hijack" sessions (or client variable data) by passing in simple values, if in fact they could find session or client data for such a "simple" cfid/cftoken pair that may exist in the server.
For more on the concept of session hijacking, which this feature was specifically added to address, see such entries as those on from wikipedia, OWASP. Here also are discussion of CF session hijacking from 2005 ("Mister Ruthsaria"), 2007 (Dave Ferguson), and 2008 (Jason Dean), so the discussion of CF session hijacking is nothing new.
But I've not seen anyone else discuss this matter that existing simple cftokens continue to be acknowledged even after this setting is enabled.
Before you freak out
As with any discussion of security, it may set some people in a panic. Sometimes it's warranted, sometimes, not so much. I am sharing info to let you decide for yourself.
For instance, the risk of hijacking (because of possible existence of simple cftoken values) depends on users having visited your site and your code having created session for them, all while they passed in the simple cfid/cftoken pair.
Once you change that admin setting, you would hope that the number of such "simple" cfid/cftoken pairs in use at any one time will decrease, as new users (who had not visited before) will get new UUID cftokens. But sessions with the simple values as keys will still exist when users still using them do visit your site, at least until their sessions timeout.
This problem is a more disconcerting with respect to client variables, since those live in the client repository (by default) for 90 days since previous use.
And to be clear (lest some people be scared without fully understanding me), this is all predicated on your having CFML code on your server that accesses the session or client scopes. I'm not talking about some vulnerability that allows hackers to somehow "magically" get access to session and client variables. Again, read up on session hijacking before getting overly concerned. And if you don't have code that uses client variables, then you have no need to worry about any implication for client variable hijacking.
Even so, I think this news (that the setting only controls creation of new cftokens, not continued use of existing simple one) may well be a surprise for some, and that's why I'm writing. I will also notify the Adobe CF and PSIRT teams, so they are aware of this. I don't know that this warrants a security alert, and there may be nothing that Adobe can really easily do (as I'll explain in a moment). I think it's just something that people ought to be aware of, if they were relying on that setting to "totally protect them from easy session/client hijacking".
Bottom line: the "Use UUID for cftoken" setting only controls the *creation* of new UUID cookies. It does not enforce a rejection of existing 8-character ones (because of that need above for real users to still be able to access existing client/session data.)
Want to test for yourself?Maybe you're the "show me" kind of person. You can test this yourself. You just need some tool that allows you to delete cookies in your browser (more in a moment). You'd want to:
- Look at the CF Admin to see what the "use uuid for cftoken" setting currently is. If it's off, keep it off. If it's on, turn it off (we'll turn it back on in a moment.)
- Create a new folder in whatever web-accessible directory you use for creating test pages
- In that new folder, create an application.cfm that has this:
<cfapplication name="cftokentest" sessionmanagement="yes" clientmanagement="yes">
We're creating a new folder with its own application.cfm so that we don't clash with any existing application.cfm or .cfc you may have in the directories above it.
- In that new folder, create a page that does a CFDUMP of the session and client scopes, and the CGI if you want, for good measure. Let's call it dumpvars.cfm:
- Visit dumpvars.cfm
(If you get an error running the following pages because you have no default client storage defined in your Admin, you could add clientstorage="registry" to the line above. It's not wise to use the registry for client variables regularly, but that's for another blog entry. And while you could use clientstorage="cookie", it could confuse matters for this entry.)
- If you had turned off the "use uuid for cftoken", you should see an 8-digit cftoken. (If you do not, it means you already had one in your browser, which proves my point.) But let's delete that cookie for now. Use whatever tool you have to delete the cookies.
(While most browsers have an option to clear "all" cookies, I'd recommend finding a finer-grained approach, to delete only those for a given domain. Any of several tools can help, including some built-right into browsers, as I discuss in a blog entry, Need to solve browser problems? Did you know most modern browsers now have built-in developer tools?. I also point there to alternative tools like firebug, charles, etc.)
- Refresh the page and confirm that you do now see (or still see) an 8-digit cftoken.
- Create a page to update a variable in the session and client scopes. Let's call it setvars.cfm:
- Visit dumpvars.cfm again, and you should see the values you just set.
- In the CF admin, turn on "use uuid for cftoken".
Update: here is the point where, if you DO have the APSB 11-04 or later hotfix applied, and do not restart CF, then you will still see the behavior I discuss here, and the next will show that the old 8-digit cftoken is still used, at least until you do next do a restart. Since many may not know about this, it's is at least a temporary vulnerability.
- Visit dumpvars.cfm again, and you should see no change. The same cfid/cftoken is used, and the values you just set are still there. This shows that changing that setting does NOT block contiued use of simple cftoken values.
- Clear the cookies again, and refresh the dumpvars.cfm page. You should now see that you have a new cfid/cftoken pair, and the cftoken is now a UUID (which shows that you do NOT need to restart CF after turning this setting on). But note that the variables you set are gone. The point is, you have a new CFID/CFTOKEN pair, and can therefore no longer access the variables created for use by that previous cfid/cftoken pair. But in this case, it's what we'd expect because you did in fact delete the cookies.
- If you had originally had "use uuid for cftoken" turned off, you may want to turn it back on (to revert to what you were using beforehand). But then it is in your interest to use that setting for protection. And as this entry shows, it will not affect existing clients and client/session variables. (But do note that if you have code that manipulates the cftoken value, such as validating it, storing it in a database of your own, etc. then beware that it will now be a much longer value, as a UUID, than it was before when this setting was not enabled.)
So there you have it.
What could be done, going forward?
- Again, if you are on CF 10, or on CF 8 or9 with at least that APSB 11-04 or later security hotfix applied, then you are covered, at least as long as you restart CF after turning on "use uuid for cftoken".
- But if you *are* on CF 10, or are on CF 8 or 9 with at least that APSB 11-04 or later security hotfix applied, but you have turned off the sessionfixation protection as I discussed at the opening of the entry, then you will remain vulnerable to this until you turn back on that session fixation protection.
- And of course, if you are on 8 or 9 and have not applied that security hotfix or above, then you will remain vulnerable.
And now that I realize that the new sessionfixation protection will cover us, at least if we restart CF after making the change, my proposal of other possible fixes is now moot, so I will strike them out.
I suppose one could argue that an option should be added that forced CF to reject any such 8-token CFTOKENs. I'll leave it to others to raise a feature request for that, or point out if it already exists. (And someone may well have raised this as a "bug" already, but if the CF team regarded it as a security issue, it would be marked private and you couldn't see it.)
If Adobe were to add the an option to reject simple cftokens, I'd asset that should remain just an option, though, and not become a default if uses "use uuid for cftoken". Again, rejecting existing cftoken values would mean loss of connection to existing client and session data for users still using the old cfid/cftoken pairs. That would not likely be what everyone would want to happen! (And the fact that it does not is why I think this issue has remained quietly unobserved for so long.)
Someone might propose that still another option would be to have CF swap out the old cftoken for a new one, in a transparent way, just like the new sessionrotation feature in CF10 does change out tokens on the fly to address session fixation issues. Unfortunately, this would still require CF to allow a request to come in with old "simple" cftokens, so the hijacking vulnerability would be there, it seems. But maybe folks on the CF team (or a reader here) will see some opportunity I don't.
And indeed, I think this thorny challenge to solving things is why this problem was never solved. There doesn't seem any easy way to remap existing users to their existing session/client variables while also blocking access to these simple cftoken values.
It pays to watch the incoming cookies, when trying to understand session/client variable challenges
Finally, I'll note that one reader on the discussion list in question did acknowledge that this situation did also explain an odd behavior he had noticed. I suspect it could, especially for those who may do manipulation of these cfid/cftoken values, especially if they didn't fathom that this was happening (simple CFID values were still being accepted).
This is why I always stress the value of dumping the CGI scope, which shows what the *incoming cookies* are, when trying to debug problems with respect to session or client variables. So often people will say "my users keep losing session variables", but then they may not notice that for some reason the user is not passing in any cfid/cftoken (or jsessionid) values. "No tickee no washee", as the old saying went. But if you dumped the cookie scope instead, especially after your application.cfc or .cfm ran (specifically cfapplication within application.cfm), then the cookie scope would show values created by CF, even if none came in one the request.
Hope something above in all that helps someone.
(PS. I did my testing of this on CF 9.0.2 and CF10, getting the same results.)