Safeguard
Application Security•

CWE-500 Public Static Field Not Marked Final: Risk and Fix

A public static field without final can be read and changed by any class in the application. How it goes wrong in Java and C++ and how to lock it down.

Safeguard Security Team
3 min read

CWE-500 is an object that contains a public static field that is not marked final, which may allow it to be modified in unexpected ways. MITRE lists C++ and Java as the affected languages.

How it happens

MITRE puts it plainly: public static variables can be read without an accessor and changed without a mutator by any class in the application. There is no gate, no validation and no owner. One module sets a value, another module trusts it.

This often starts as a convenient global, such as a default configuration object, a flag or a shared list.

// Vulnerable: any class can replace or edit this
public class Settings {
    public static String[] ALLOWED_HOSTS = {"api.example.com"};
    public static boolean DEBUG = false;
}

// elsewhere in the app
Settings.ALLOWED_HOSTS[0] = "evil.example.net";
Settings.DEBUG = true;

Even a final array has changeable contents, so a constant reference to a mutable object is not enough on its own.

What an attacker gains

MITRE lists two impacts. Integrity: the object could potentially be tampered with. Confidentiality: the object could potentially be read. Anything running in the same application, including a compromised or untrusted plugin or library, gets that access.

How to find it

Static analysis can find some instances. A quick code search also works: look for public static declarations that lack final in Java, and for non-const globals in C++. Then ask what each one controls.

How to fix it

MITRE gives two steps.

  1. At design time, identify the scope of each critical data element, including whether it should be static at all.
  2. In code, make static fields private and constant. That means final in Java and const in C and C++.
public final class Settings {
    private static final List<String> ALLOWED_HOSTS =
        List.of("api.example.com");

    public static List<String> allowedHosts() { return ALLOWED_HOSTS; }
}

List.of returns an unmodifiable list, so callers can read the values but not change them. If a value truly has to change at runtime, expose a method that validates the change and keep the field private.

Quick check

Is a public static final array safe?

Not fully. The reference cannot change, but the elements can. Use an unmodifiable collection or return a copy.

What two keywords does MITRE point to for constants?

const in C and C++, and final in Java.

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.