DEV Community

Cover image for Safely Fetching Scoped Variables (while avoiding Scope Injection)
James Moberg
James Moberg

Posted on

Safely Fetching Scoped Variables (while avoiding Scope Injection)

I'm testing some ideas. I'm not sure if I'm on the right path or not, but thought I'd share.

I have some UDF & CFC libraries that we've built over the year and I have some checks to determine whether default application variables exist and use them to override default values. In order to avoid possible "Scope Injection" & errors (when scopes don't exist), I thought I'd attempt to write a function that uses "safe navigation" to verify scope classname, verify key (in the struct keylist) and return the value (w/optional fallback).

I've included a simple example where application.randomVarName_xxx is injected into the URL & FORM scopes on a script that doesn't use an application CFC or CFM file. As a result, dumping the application value actually returns url.application.randomVarName_xxx instead of a non-existent application-scoped value.

Another example is the retrieval of a server variable with a default value (if it doesn't exist).

Here's a little bit of my post-CFSummit2022 discussion of this on Twitter. https://twitter.com/gamesover/status/1578154242031767553

  • Yeah... I tend to use structKeyExists (or struct.keyExists("keyname")) when the key names are dynamic/random... but yeah, isdefined does reach out to all other scopes if it can't find it. Too bad there's no option to limit searching to within a specific scope. - Me
  • Short term that would be an easy UDF to write and share on GitHub. Longer term that would be a nice upgrade to IsDefined() they could implement ala updates to StructNew() - Nolan

Here's the source code proof-of-concept. Let me know your thoughts.

NOTE: I'd provide a direct link to TryCF.com, but I noticed that gists are permanently cached and never refresh. If you want to test it there, please copy-and-paste the code.

https://gist.github.com/JamoCA/7e544f1488a703d868cecc2b7ae5c2ed

Top comments (2)

Collapse
 
bennadel profile image
Ben Nadel • Edited

So, just looking for clarity, does this only matter if the variable in question does not exist? Meaning, is the url scoped checked for application.foo only if application.foo doesn't exist? Or does it have to do with scope precedence?

Oh, actually I see in the article from Pete that you mentioned, that it only does this if the variable doesn't exist.

Collapse
 
gamesover profile image
James Moberg

Even if the variable does exist, what if it's not from the exact scope that you are expecting it to be from? I've seen some lazy CFML and have helped some developers that weren't aware of what was happening since they tended to reuse the same variable names within multiple scopes. I've now found that it's best to "be explicit" and "trust, but verify". (I credit my "dotNet blood brother" for the "trust, but verify" mantra as he works in a var-typed environment and is constantly encountering issues like this from other developers that he manages.)