DevLearningTools

MODULE 6 · LESSON 05

Variable Scope

How variable scope works inside a ColdFusion function — the VARIABLES and LOCAL scopes, the var keyword, ColdFusion's full scope-lookup order, and a real security gotcha around unscoped variables.

New lessons are added one at a time as the course gets built out — a graded quiz for each lesson is still on the way.

Every variable in ColdFusion lives in a scope — a named container that determines who can see it and how long it lasts. Get scoping wrong inside a function and a variable can silently leak into the page that called it, overwrite another request's data, or worse.

Learning Objectives

After completing this lesson, you'll be able to:

  • Explain what the default VARIABLES scope is and its limits.
  • Use var to keep a function's local variables from leaking out.
  • State ColdFusion's scope-lookup order for unscoped variable names.
  • Recognize the real security risk of leaving user-facing variables unscoped.

The Default: VARIABLES Scope

Any variable set without an explicit scope prefix on a .cfm page gets the VARIABLES scope automatically — myVar and variables.myVar are the same thing. It's only accessible within that page (and pages it includes), not from other requests or other pages.

CFScript
Simulated output — illustrative only, not a live ColdFusion/Lucee server.
Tag Syntax
Simulated output — illustrative only, not a live ColdFusion/Lucee server.

Inside a Function: LOCAL Scope and var

Variables declared with var inside a function belong to that function's own LOCAL scope — they exist only for the duration of that call and don't collide with a page-level variable of the same name.

CFScript
Simulated output — illustrative only, not a live ColdFusion/Lucee server.
Tag Syntax
Simulated output — illustrative only, not a live ColdFusion/Lucee server.
NOTE

Leave out var inside a function and ColdFusion assigns the VARIABLES scope instead — the variable silently leaks out to the calling page, which is rarely what's intended.

Scope-Lookup Order

When a variable name has no explicit scope prefix, ColdFusion searches through scopes in a fixed order until it finds a match. This is the full order, from first-checked to last:

OrderScope
1Local (function-local, var-declared)
2Arguments
3Thread local
4Query (inside a query loop)
5Thread
6Variables
7CGI
8cffile
9URL
10Form
11Cookie
12Client
NOTE

Notice URL and Form are near the bottom of the list, checked one after the other — that's the exact mechanism behind the next section's security gotcha.

The Real Gotcha: Unscoped Variables Are a Security Risk

Because URL is checked before Form in the lookup order, an unscoped variable name that matches both a URL parameter and a form field will silently resolve to whichever one ColdFusion finds first — usually not the one the code was written expecting.

This becomes a genuine cross-site scripting (XSS) risk: if a page reads an unscoped search variable expecting it to come from a submitted form, an attacker can supply the same name as a URL parameter instead — ?search=<script>...</script> — and have it accepted and rendered the same way.

CFScript — Vulnerable
<cfscript>

if (isDefined("search")) {
    writeOutput("You searched for: " & search); // could be url.search OR form.search
}

</cfscript>
Tag Syntax — Vulnerable
<cfif isDefined("search")>
    You searched for: <cfoutput>#search#</cfoutput>
    <!--- could be url.search OR form.search --->
</cfif>
CFScript — Fixed
<cfscript>

if (structKeyExists(form, "search")) {
    writeOutput("You searched for: " & encodeForHtml(form.search));
}

</cfscript>
Tag Syntax — Fixed
<cfif structKeyExists(form, "search")>
    You searched for: <cfoutput>#encodeForHtml(form.search)#</cfoutput>
</cfif>
NOTE

Explicitly scoping the variable (form.search, not search) removes the ambiguity entirely — the code only ever reads from the source it was written for.

Common Beginner Mistakes

Forgetting var on a function-local variable

Without var, ColdFusion assigns the VARIABLES scope, which can silently overwrite a page-level variable of the same name and leak state between calls.

Reading form/url data without an explicit scope prefix

This relies on ColdFusion's scope-lookup order picking the source you meant, which isn't guaranteed and opens the door to the URL/Form ambiguity described above. Always write form.fieldname or url.paramname explicitly.

Declaring var statements after other code in a function

In CFScript, var declarations should come first in the function body — declaring them partway through works in practice but is a bad habit that makes the function harder to read.

Best Practices

  • Explicitly scope every variable you can — form.x, url.x, variables.x — instead of relying on the lookup order.
  • Always use var for a function's local variables, even in a small function where a leak seems unlikely.
  • Run any user-facing output that originated from form/url/cookie data through encodeForHtml() (or the equivalent) before writing it back to the page.

Interview Questions

What happens if you forget var on a variable inside a function?

ColdFusion assigns it the VARIABLES scope by default, so it becomes visible to (and can overwrite) variables outside the function, instead of staying local to that call.

Why is leaving form/URL variables unscoped a security concern?

Because URL is checked before Form in ColdFusion's scope-lookup order, an attacker can supply a URL parameter with the same name as an expected form field and have it silently accepted — a classic reflected-XSS vector if the value is ever output without encoding.

Which scope do variables declared with var inside a function belong to?

The Local (function-local) scope — the very first scope checked in ColdFusion's lookup order, and the one that exists only for the duration of that function call.

Summary

In this lesson, you covered the default VARIABLES scope, using var to keep function-local variables from leaking, the full scope-lookup order, and a real security gotcha where unscoped variables create ambiguity between URL and Form data.

That wraps up the core mechanics of writing functions in ColdFusion.

What's Next?

The final lesson in this module covers recursion — functions that call themselves, with a base case, an accumulator pattern, and the scoping habits that keep recursive calls from interfering with each other.