CWE-1120 says the code is too complex, as calculated using a well-defined, quantitative measure. The important phrase is the last one. This is not a feeling that the code is messy. It is a score against a metric that crosses a threshold you chose.
MITRE classifies it as a class level entry under CWE-710, improper adherence to coding standards. Its usage is allowed with review, because as a class it may have a more precise child entry that fits better. Its children include excessive McCabe cyclomatic complexity (CWE-1121), excessive Halstead complexity (CWE-1122), excessively deep nesting (CWE-1124) and others.
How it happens
Complexity accumulates. Every special case, feature flag and defensive check adds a branch. No single change looks large. The function that began with ten lines ends up with three hundred, and nobody had a moment where it felt like the right time to split it.
What an attacker gains
MITRE lists two consequences, both under the other scope.
The first is reduced maintainability and increased analytical complexity. The issue makes the product harder to understand and maintain, which indirectly affects security by making vulnerabilities more difficult or time-consuming to find and fix, and might make them easier to introduce.
The second is reduced performance. MITRE says the issue can make the product perform more slowly, and that if the relevant code is reachable by an attacker, the performance problem might introduce a vulnerability. That is the case where slow code on an attacker-reachable path becomes a denial of service concern.
How to find it
MITRE notes that static analysis, often called SAST, can find some instances by analysing source code without running it. In practice:
- Choose a metric your tools can compute, such as cyclomatic complexity.
- Pick a threshold, and apply it per function.
- Report the worst offenders first. A ranked list is more useful than a long flat one.
- Cross-check against security sensitive areas: parsers, authentication, authorization and input handling deserve the lowest thresholds.
How to fix it
The record lists no formal mitigations. Reliable practices:
- Split functions. Extract named helpers so each does one thing.
- Use early returns to remove deep chains of else branches.
- Replace long conditional chains with lookup tables or polymorphism where it reads better.
- Gate new code. Add the metric to CI so a function over the limit fails review instead of joining the pile.
- Do not refactor blindly. Add tests around a complex function before changing it, particularly in security checks, so the cleanup cannot silently alter behaviour.
# Before: nested branches
def can_access(user, doc):
if user:
if user.active:
if doc.public:
return True
else:
if user.id == doc.owner:
return True
return False
# After: flat, same behaviour
def can_access(user, doc):
if not user or not user.active:
return False
return doc.public or user.id == doc.owner
Try it yourself
A static scan is the quickest way to see where your own code scores badly. This demo shows a code scan from start to finish.
Click through it at your own pace, or open it full screen.
Quick check
Why does MITRE say the measure must be well defined?
Because the weakness is a threshold crossed on a metric, not a matter of opinion. That makes it checkable and repeatable.
When can complexity become a vulnerability?
When slow code is reachable by an attacker, MITRE notes the performance problem might introduce a vulnerability.