Safeguard
Application Security•

CWE-1108 Excessive Reliance on Global Variables: What to Do

Global state makes code hard to reason about and harder to audit. How CWE-1108 happens, what it costs security reviewers, and how to narrow scope.

Safeguard Security Team
4 min read

CWE-1108 covers code that depends too heavily on reading and writing global variables at many points, instead of keeping the information in a narrower, more local context. Any language with module or process level state can have it, and MITRE lists it as not language specific.

Unlike most quality entries in this range, MITRE allows this one to be mapped to real vulnerabilities, with the usual caution to read the name and description carefully and not force a fit. It is a base level weakness, and it sits under CWE-1076, insufficient adherence to expected conventions.

How it happens

Globals are the path of least resistance. A function needs a value that lives three calls up, and instead of passing it down, the developer reads a shared variable. Another function needs to signal a result, so it sets a flag that others check later.

After a while the program's behaviour depends on the order in which unrelated functions touch shared state. The reasoning that used to fit inside one function now needs the whole program in your head.

What an attacker gains

MITRE lists two consequences, both in the other category: reduced maintainability and increased analytical complexity. The explanation is that the issue makes the product harder to maintain, which indirectly affects security by making it more difficult or time-consuming to find and fix vulnerabilities, and might make it easier to introduce them.

So the attacker gains an indirect advantage. State that any code can change is state an attacker may be able to influence through some unexpected path. Reviewers find it harder to prove that a security decision, such as an authorization flag, is set once and never overwritten by another code path.

How to find it

MITRE notes that static analysis can find some instances by modelling code without running it. Practical checks include:

  1. List every global or module level mutable variable and count the functions that write to it.
  2. Flag globals that are written in more than one file.
  3. Look for functions that behave differently depending on a global the caller never passed in.
  4. In review, ask for any security relevant flag to have a single, obvious writer.

How to fix it

The record lists no formal mitigations. These are widely used practices.

  • Pass values explicitly. Hand data to functions through parameters and return values rather than shared variables.
  • Narrow the scope. Make state local, or private to a module or object, and expose it only through a small interface.
  • Prefer constants over mutable globals. Read-only shared values are far less risky than values anyone can reassign.
  • Group related state. If several functions genuinely share a set of values, put them in a structure or object that is created, passed and owned deliberately.
  • Isolate security decisions. Keep authorization results and similar flags in the narrowest scope possible so no distant code can flip them.

A small example:

# Before: hidden coupling through a global
is_admin = False

def load_user(u):
    global is_admin
    is_admin = u.role == "admin"

def delete_record(rec):
    if is_admin:
        rec.delete()

# After: the decision travels with the call
def delete_record(rec, user):
    if user.role == "admin":
        rec.delete()

In the second version nobody can change the result by calling an unrelated function first.

Quick check

Are all global variables a problem?

No. The weakness is excessive reliance. A small number of well-understood, read-only shared values is normal. The trouble is widespread mutable state touched from many places.

Why does this matter to security rather than just style?

Because MITRE describes the effect as making vulnerabilities harder to find and fix and easier to introduce. Code that is hard to reason about is hard to audit.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.