ColdFusion searchImplicitScopes and APSB24-14
By Pete Freitag
Adobe has published a ColdFusion Security Hotfix APSB24-14 today which describes "a critical vulnerability that could lead to arbitrary file system read".
One of the things you will want to take special note of in this hotfix is that a major change was made to how ColdFusion handles unscoped variables. According to the technote:
Starting with this update, ColdFusion will default to searchimplicitscopes=FALSE
and if a variable name is not prefixed with a scope identifier, an error is returned*
* Clarification: not all unscoped variables will throw an error. It will throw an error (coldfusion.runtime.UndefinedVariableException: Variable X is undefined
) if the unscoped variable is only defined in the form, url, cgi or cookie scopes.
What will break:
This means that if you have some code like this:
<cfoutput encodefor="html"> Hi, my name is: #name# </cfoutput>
With searchImplicitScopes=false
you can no longer use #name#
as a short cut for #url.name#
or #form.name#
, etc.
So the above code would need to be rewritten to explicitly name the scope, for example:
<cfoutput encodefor="html"> Hi, my name is: #form.name# </cfoutput>
What will still work:
Code like this will still work:
<cfset name="Pete"> <cfoutput encodefor="html"> Hi, my name is: #name# </cfoutput>
Because it will search the variables
scope and find that I have set the name
variable.
In a function the arguments
or local
scope will be searched, but it will not cascade to additional scopes. So the following code will still work fine with searchImplicitScopes=false
:
function greet(name="Pete") { var greeting = "Hi "; return greeting & name; }
Use of unscoped query variables will also continue to work, so something like this still works:
<cfoutput query="news" encodefor="html"> #story# </cfoutput>
Assuming that story
is a column in the news query.
Workarounds
You can disable this change by setting this.searchImplicitScopes=true
in Application.cfc
, or <cfapplication searchImplicitScopes="true">
in Application.cfm
, or globally by adding the system property -Dcoldfusion.searchimplicitscopes=true
, however Adobe says:
This option is highly discouraged and should be considered only as a temporary workaround, until all application code is fixed
Please also note that Adobe states:
The JVM flag -Dcoldfusion.searchimplicitscopes
will be removed in the next major release of ColdFusion
I would assume that the Application level settings will remain intact, but that remains to be seen.
It is not really clear what the risk is that they are addressing, it would be great to get some more info from Adobe on this.
There is a risk of un-scoped variables that I call scope injection, I don't know if it is related to this issue or not. I have been talking about scope injection in my ColdFusion security training class, and I first wrote about it on my blog back in 2015.
To help find this issue in your code, I am considering adding a scanner to find un-scoped variables to my CFML code security scanner, Fixinator. Please let me know if you'd like to see that feature added to Fixinator.
UPDATE: On March 24, 2024 I added the ability for Fixinator to find and fix unscoped variables in your ColdFusion code.
UPDATE: On April 1, 2024 Adobe has created a patch which will log unscoped variables.
ColdFusion searchImplicitScopes and APSB24-14 was first published on March 12, 2024.
If you like reading about coldfusion, security, or adobe then you might also like:
- HackMyCF Updated for APSB11-29 Security Hotfix
- Adobe eSeminar on FuseGuard
- Recent ColdFusion Security Hotfix Updated Feb 2011
- Path Traversal Vulnerability Security Hotfix for ColdFusion Released
The FuseGuard Web Application Firewall for ColdFusion & CFML is a high performance, customizable engine that blocks various attacks against your ColdFusion applications.
CFBreak
The weekly newsletter for the CFML Community
Comments
For the Application.cfc version, it would go inside a cfset tag if you are using a tag based component. Otherwise in a script based component it would just be a single line statement. In both cases you put it in the "constructor" area of the component, that is within the cfcomponent tag, or component block, but outside of your functions.
As for the prospect of "adding a scanner to find un-scoped variables" in Fixinator, that could surely be valuable. I do hope you'd try to account for the fact that it's not ALL unscoped variables that should be flagged, as that would lead to false positives.
As you clarify in your guide on scope injection (saying that for readers here), unscoped variables are only vulnerable (will only fail with this update's change in default behavior) if they would NOT be resolved by searching in scopes that are WITHIN the request, like variables, local, arguments, query.
The problem folks need to beware is that if such unscoped variables were NOT resolved in that search, then the implicitscopesearch=true let it proceed to search "outside" scopes, like cgi, url, form, cookie, etc. which exposed them to outside manipulation--as your example in the guide does a great job showing (and I also discuss this more in my own post on the update (https://www.carehart.org/blog/2024/3/12/cf_updates_march_2024_possible_breaking_change).
I do appreciate that it may be very difficult to perform that kind of runtime evaluation in Fixinator--but it's pretty amazing so I won't put it past you to solve! :-) And maybe doing that level of checking could be based on your tools confidence/severity flags.
Hope that's helpful, to you and readers.
@Charlie - thanks for posting a link to your entry, I saw it but haven’t had a chance to update my entry to point to it for more info. Great clarifications and info in there.
As for Fixinator it is challenging and maybe impossible to really know for sure if an unscoped variable is going to cascade up to the form, url, cgi, cookie scope. So yes I would plan to use the confidence level setting in fixinator to account for that. And in some cases like when a variable is set in the variables scope above the unscoped use, we can assume it is ok to remain unscoped.Though some may still want to find those and some may want to ignore them.
Can this also be added to Application.cfm?
How do I add it? Are there tags that surround 'this.searchImplicitScopes=true'