Pete Freitag Pete Freitag

Fixinator 6.1.0 - Detecting Undefined Remote Arguments

Published on May 29, 2025
By Pete Freitag
coldfusion

Today, I released Fixinator version 6.1.0 which includes several enhancements to the CFML code security scanning to provide more accurate results. This release also updates the Adobe ColdFusion compatibility scanner to account for the breaking change in the latest ColdFusion security update (ColdFusion 2025 Update 2, ColdFusion 2023 Update 14, ColdFusion 2021 Update 20).

Adobe Compatibility: Undefined arguments in remote functions

Fixinator now detects the use of use of undefined arguments in a remote function. Here's an example of a function that will trigger this error:

component {

    remote string function example(x=0) {
        if (structKeyExists(arguments, "y")) {
            return arguments.y;
        }
        return arguments.x;
    }

}

On the latest versions of ColdFusion 2021, 2023 and 2025 you will get an error if you pass the argument y (or any argument name besides x) to the remote function. The error you might get looks like this:

coldfusion.runtime.UDFMethod$IllegalArgumentException: Function example does not support y as an argument in c:\inetpub\wwwroot\example.cfc at coldfusion.runtime.UDFMethod.validateArguments

It is worth pointing out that this error will occur on the remote function even if it is not accessed as a remote function. So you can fix this issue by making the function public instead of remote if you are not calling it as a web service or as /example.cfc?method=example&y=1.

So if you want to scan your source code for this type of issue, you can run a ColdFusion 2025 compatibility scan like this:

fixinator path=c:\mycode\ goals=compatibility engines=adobe@2025

Fixinator will tag the above function with a message like this:

As of ColdFusion 2025 update 2, 2023 update 14, and 2021 update 20 you can no longer use undefined arguments in a remote function. This can be overridden by system properties, but is not recommended for security purposes.

The system property that controls this feature is named coldfusion.runtime.remotemethod.matchArguments, and it defaults to true. You can disable the feature by setting the java system property:

-Dcoldfusion.runtime.remotemethod.matchArguments=false

The above would be added in your jvm.config or in the ColdFusion administrator (requires restarting ColdFusion).

I've updated my list of ColdFusion 2025 breaking changes to include this issue as well.

Other improvements

A few other minor improvements include support for --json which returns your fixinator results as json, and --forceLocal which is used for the enterprise version to ensure that the scan is conducted locally.

Go and grab a trial of Fixinator, and scan your ColdFusion code!



fixinator coldfusion compatibility security

Fixinator 6.1.0 - Detecting Undefined Remote Arguments was first published on May 29, 2025.

If you like reading about fixinator, coldfusion, compatibility, or security then you might also like:

FuseGuard Web App Firewall for ColdFusion

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

That's such great news, Pete. Thanks for the efforts and the news.

Can you clarify if you're also able to detect the less obvious aspect of this update, where the mere existence of any url or form vars (defined anywhere in the flow of execution of the call to such a remote method) will ALSO cause those vars to be passed in by cf, implicitly--which thus fails now if they are not defined as args?

I suspect this is harder for you to detect, as it's more a runtime impact that's hard to find via static analysis. But people who hit it will wonder.
by Charlie Arehart on 05/30/2025 at 1:29:59 AM UTC
Thanks Charlie - yeah it is quite a bit harder to reliably detect that scenario, but I will think about that and see if I can come up with a way.
by Pete Freitag on 05/30/2025 at 1:38:43 PM UTC
This is completely breaking sending arrays as form data to a remote function.

<form action="/remote.cfc?method=cfpatchtest" method="POST">
<input name="person[1]" value="Stefan" type="text">
<input name="person[2]" value="John" type="text">
<input type="submit">
</form>

Would arrive as an array form.person but with this its always rejecting it because person[1] cannot be defined as an argument for the cfpatchtest remote function.

Unless I'm not seeing something here I would need to #1 completely rewrite the way the data arrives or #2 just deactive this. We all know #1 is not happening ;)
by Stefan Negele on 06/10/2025 at 10:06:56 AM UTC
@Stefan - Do you have person defined as an argument with type="array"? If so then that sounds like a bug to me, I would submit that to Adobe's BugTracker. There are a few other oddities with this update, such as having to add returnformat as an argument, which I also think should be considered a bug.
by Pete Freitag on 06/10/2025 at 3:37:39 PM UTC
Stefan, I appreciate your frustration. But I don't think the problem is as you propose it. I have run a test of your code on CF2018 (which was NOT updated for this change like CF2021 and above).

When I setup a remote.cfc with that cfpatchtest as a remote method, and I dump the arguments scope for those fields as passed in from that form, it is NOT an array. Instead, it's simply two variables named respectively "person[1]" and "person[2]" (those literal strings, as found within the arguments scope, which like all scopes is itself a struct). Here's a text version of the cfdump of that arguments scope, adding a label="arguments":

arguments - struct
PERSON[1] Stefan
PERSON[2] John

If instead those fields were indeed passed in as an array, they would appear within the struct as an array called person. More specifically, I did a cfdump var="#arguments.person#" and none existed (again this was in CF2018).

So if you look at your code, did you REALLY somehow process those arguments as an array called person? in your cfpatchtest method, if run on a CF version before the update? or in the "real" code in your app from which you maybe created this simulation?

If not, then it seems the problem you're hitting is that since those come in simply as variables with names like "person[1]" and "person[2]" (again, this is in CF2018--BEFORE that update), then given that you "must define the incoming arguments" since the update, you're simply not allowed to try to define variables with brackets in the name. For instance, if you tried to do a cfargument like this:

<cfargument name="person[1]">

That gets an error, "Invalid argument name. The name person[1] used for an argument has illegal characters in it." Again, this was on CF2018--BEFORE the update.

(In case somehow Pete's blog here removes the brackets in my example, here it is without them: cfargument name="person[1]".)

Maybe someone else will see a way to define variables with such names, but if not, there is one more possibility to consider. If you just define the two form fields as simply being named "person", then CF will receive them as either a list or as an array--depending on the application-level setting called sameformfieldsasarray. If true, they will be an array: if false, they will be a list.

And if you DO have them come in as an array, then as pete says you can just then add type="array" to that cfargument and then the code will work after this update...but again your code then really DOES need to treat arguments.person as an array, which it seemed was your original desire.

Hope that helps. Please don't shoot the messenger. I don't work for Adobe, and I'm not arguing with you, just offering explanation and trying to help you find a solution.
by Charlie Arehart on 06/10/2025 at 7:58:03 PM UTC
So sorry about all of this. I was delusional in thinking that it arrives in an neatly packed array variable. Even in CF2021 before the patch all the form parameters arrive in a structure and with the string as you said form["person[1]"] = "Stefan". I was so sure its an array the error threw me completely off. Maybe I was thinking of php where this is being transferred into an array, I dont know anymore.

Right now we're treating the form variable names as strings and then go through them in a loop starting with 1.. and then looking for structKeyExists(form, "person[#local.i#]") and go from there. At least we weren't using the evaluate() function ;)

The patch broke this trick. We need to figure out how to have a variable number of form parameters because as you said brackets cannot be part of an argument name and never were and thats what we would need here. I need to change all the variable names, which might be pain because then I would need to define an army of cfarguments count from 1 to ... 100 or simple just put everything in a json string and just send one parameter and then with my luck run into deserializejson() security issues..

Problem here is that we are using datatables.net and their ajax code of loading data is using these type of array parameters

columns[0][data]
columns[0][name]
columns[0][searchable]
columns[0][orderable]

Thats basically what they are sending to the remote method to control the first column.. since that security patch treats both url and form parameters as arguments and need to be defined... Just won't work anymore.

Thanks for testing it. I dont see anything wrong with how they implemented it other than that they did not advertise the form parameters to be part of the cfargument checking.
by Stefan Negele on 06/10/2025 at 8:49:37 PM UTC

Post a Comment