CWE-547, Use of Hard-coded, Security-relevant Constants, is about using literal values instead of named ones for things that matter to security. MITRE says this increases the likelihood of mistakes during code maintenance or a change of security policy.
How it happens
A role number, a retry limit, a minimum password length or a timeout gets typed directly into a condition. It works. Then the same literal appears in a second file, and a third.
// Vulnerable to drift: the meaning of 3 is lost, and it is repeated
if (user.getRole() == 3) { allowAdmin(); }
...
if (user.getRole() == 3 || user.getRole() == 4) { showAuditLog(); }
When policy changes, someone has to find every copy. MITRE describes the risk: if the developer does not find all occurrences of the hard-coded constants, an incorrect policy decision may be made when one of them is not changed. Once the software is released into the field, changing values may be difficult or impossible because it takes code changes.
There is also a disclosure angle. These hard-coded values may become available to attackers if the code is ever disclosed.
What an attacker gains
MITRE lists effects that vary by context, with quality degradation and reduced maintainability. The security result is indirect. A limit left at its old value in one corner of the code is the kind of gap an attacker finds by testing each path.
How to find it
- Search conditions on security checks for bare numbers and strings, such as role IDs, limits and lengths.
- Look for the same literal in several places.
- MITRE notes static analysis can find some instances of this weakness.
How to fix it
MITRE's advice: avoid hard-coded constants, and note that configuration files offer a more flexible solution. Steps:
- Give each security-relevant value a name and define it in one place.
- Where it should change without a release, move it to configuration.
- Reference the name everywhere, so a policy change is one edit.
public enum Role { USER, EDITOR, AUDITOR, ADMIN }
if (user.getRole() == Role.ADMIN) { allowAdmin(); }
Do not confuse this with secrets. A configuration file is the right home for tunable policy values. Credentials belong in a secrets store.
Quick check
What is the main risk of repeating a literal like 3 across files?
A policy change can miss one copy, leaving an incorrect decision in place. A named constant makes the change a single edit.