CWE-637, Unnecessary Complexity in Protection Mechanism (Not Using 'Economy of Mechanism'), is a design weakness. The product uses a more complex mechanism than necessary, and that complexity leads to trouble when the mechanism is not correctly understood, modeled, configured, implemented or used.
This is a Class level entry, which means it describes a principle more than a single bug. It is useful because it explains why many specific bugs exist.
How it happens
MITRE puts the principle plainly: security mechanisms should be as simple as possible. Complex mechanisms invite partial implementations and compatibility problems, and the result is a mismatch between the assumptions of the designer and the behavior of the code.
A corollary applies to data. Complex data specifications lead to complex validation code. If a format has many ways to say the same thing, the validator must handle every one, and attackers look for the one it missed. Likewise, complex tasks and systems may need complex security checks, so simple systems are easier to protect.
Think of a house with eight doors. Each lock may be good. The house is still harder to secure than one with two doors.
What the record shows
The observed examples on the MITRE page make the point concrete. Each is a case where the protection was reasonable on its own, but the surrounding system was more complex than the developer realized.
- A product supported complex regular expressions, and that led to an algorithmic complexity weakness (CVE-2007-6067).
- A developer could have inferred file type from the filename extension or the Content-Type header, but checked only the Content-Type, which enabled unrestricted file upload.
- In Apache environments, a name such as
filename.php.gifcan be redirected to the PHP interpreter instead of being served as an image. A developer who did not know this checked only the last extension. - A developer cleansed the
$_REQUESTsuperglobal array, but PHP also populates$_GET, so attackers bypassed the protection and conducted SQL injection against code that used$_GET.
In each case there were two or more routes to the same thing, and the check covered only one. Complexity created the second route.
// Cleans one of several places where the same data arrives
$_REQUEST['id'] = intval($_REQUEST['id']);
$row = query("SELECT * FROM t WHERE id = " . $_GET['id']); // untouched
// One path, one validation, parameterized query
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
$stmt = $pdo->prepare("SELECT * FROM t WHERE id = ?");
$stmt->execute([$id]);
What an attacker gains
The record lists the impact as "Other". That fits, because complexity is not an attack in itself. It is the condition that lets other weaknesses in. In the examples above those included algorithmic complexity, unrestricted file upload and SQL injection.
How to find it
The record lists no detection methods, and automated tools do not flag "too complex" reliably. Use design review instead:
- For each security control, write down in one sentence what it protects and how.
- Count the places the same input can arrive or the same decision is made. Every extra place needs its own check.
- Look for controls that depend on knowledge of another system's quirks, such as how a web server maps file extensions.
- Ask whether a simpler mechanism would meet the same requirement.
If step one takes a paragraph instead of a sentence, that is a sign.
How to fix it
MITRE's mitigation is a set of design principles for the architecture phase:
- Avoid complex security mechanisms when simpler ones would meet requirements.
- Avoid complex data models and unnecessarily complex operations.
- Adopt architectures that provide guarantees, simplify understanding through elegance and abstraction, and can be implemented similarly.
- Modularize, isolate and do not trust complex code, and apply other secure programming principles on these modules, such as least privilege.
Some concrete ways to follow this:
- Validate once, at a single choke point, instead of in many places.
- Use one input source. If the framework offers three arrays for the same data, read from one and ignore the rest.
- Decide file type from content that you inspect on the server, not from several client-provided hints.
- Limit the features of parsers you expose to untrusted input. A regex engine that supports fewer constructs is easier to reason about.
- Run complex components, such as parsers and converters, with reduced privileges.
Complexity also hides in dependencies. Each library you add brings its own mechanisms and its own quirks. Keeping an inventory of what you use, and removing what you no longer need, is a small but real application of economy of mechanism. A free in-browser dependency scan at gold.safeguard.sh/scan shows what you ship, with no login, and the file stays on your machine, up to 100 dependencies.
Quick check
Is complexity itself the vulnerability?
It is the condition. It leads to mismatched assumptions, partial implementations and checks that miss a path, and those become the actual vulnerabilities.
What went wrong in the $_REQUEST and $_GET example?
The developer cleaned $_REQUEST, but PHP also fills $_GET, so the unchecked copy still carried attacker input into a SQL query.