Most injection and memory bugs begin with the same mistake. The program accepted something it should have examined. CWE-20 is the label for that mistake, and it is a class weakness, which means it sits above many more specific entries.
MITRE's definition: the product receives input or data, but does not validate it, or validates it incorrectly, so that the input lacks the properties needed to process the data safely and correctly.
It applies to nearly everything that takes data from outside: web handlers, APIs, file parsers, message consumers, command line tools and, as the record notes, AI and ML systems.
How it happens
Input is more than a form field. MITRE's extended description lists raw data such as strings, numbers, parameters and file contents, and metadata such as headers and sizes. Data can be simple or deeply nested, with metadata and raw data layered inside each other.
Each of those has properties that matter before the code uses it. The record names many of them:
- Quantities: size, length, frequency, price, rate, number of operations, time.
- Derived quantities, such as the real size of a file instead of the size the sender claims.
- Indexes, offsets and positions into larger structures.
- Well-formedness: is the syntax correct?
- Type: is it what it appears to be?
- Consistency between elements, between raw data and metadata, and between references.
- Conformance to domain rules, such as business logic.
- Equivalence: are equivalent inputs treated the same way?
- Authenticity and ownership.
A gap in any one of these can be the entry point. The weakness is rarely a single missing check. It is usually an unstated assumption: this ID will be a number, this length is honest, this path is inside the folder.
A small example. This handler trusts the quantity it receives:
def add_to_cart(item_id, quantity):
total = price_of(item_id) * quantity # quantity never checked
charge_customer(total)
A negative quantity produces a negative charge. A huge one can overflow or exhaust memory elsewhere. The fix is to state what a valid quantity is and refuse anything else:
def add_to_cart(item_id, quantity):
if not isinstance(quantity, int) or not (1 <= quantity <= 100):
raise ValueError("quantity must be an integer from 1 to 100")
total = price_of(item_id) * quantity
charge_customer(total)
What an attacker gains
MITRE lists consequences across all three security properties.
For availability, an attacker supplying unexpected values can cause a crash, exit or restart, or take control of resource allocation so that memory and CPU are consumed.
For confidentiality, an attacker who controls resource references can read memory, files or directories.
For integrity, confidentiality and availability together, malicious input can modify memory and alter control flow, including arbitrary command execution.
The observed cases in the record show the range:
- CVE-2024-37032: a management tool for large language models did not validate the format of a digest value from an untrusted model registry, enabling relative path traversal.
- CVE-2022-45918: a chain in a learning management tool where a debugger used external input to locate earlier session logs and did not properly validate the path, allowing file system path traversal.
- CVE-2021-30860 and CVE-2021-30663: chains in a mobile operating system where improper validation led to integer overflow, exploited in the wild according to CISA's known exploited list.
Notice that two of those four lead to path traversal and two to integer overflow. Input validation failures show up under other names, which is why this class matters for classification.
How to find it
MITRE lists several detection approaches, each with a different strength.
Automated static analysis can find some instances. A tool may let you declare which of your functions perform validation, and it may know about common validation libraries. It then reports where untrusted input reaches a sensitive operation without passing through one.
Manual static analysis is needed when validation is custom. Business rules are the usual case: no tool knows that a discount cannot exceed the price unless someone checks.
Fuzzing is useful here. Feed the software unexpected inputs and watch it. It should not crash or become unstable, and it should respond with messages your application wrote. If you see exceptions or interpreter-generated errors, validation is missing.
For compiled code, MITRE also lists binary and bytecode analysis for partial coverage.
A simple checklist for review:
- List every entry point where outside data arrives.
- For each, write down what a valid value looks like.
- Find where that rule is enforced. If you cannot find it, that is the finding.
Try it yourself
Probe an API with unexpected inputs and see what a scan reports.
Click through it at your own pace, or open it full screen.
How to fix it
The record carries no mitigation list, so these steps are general practice that follows from the definition.
- Validate at the boundary. Check data when it enters the system, before it reaches business logic.
- Prefer allow lists. Describe what is valid, such as a pattern, a range, a set of values, and reject the rest. Deny lists miss new variants.
- Check type, length, range and format, in that order, and check the real size of a thing rather than the size it claims.
- Validate on the server. Client checks are convenience, not defense.
- Parse structured data with a proper parser and a schema, instead of cutting strings apart by hand.
- Normalize before you validate. Decode and canonicalize first, then check the result, so equivalent encodings are judged the same way.
- Validation is not a replacement for safe handling downstream. Still use parameterized queries and safe file APIs, so a missed check does not become an exploit.
- Fail closed with a clear error that your code wrote, not an interpreter's message.
- Keep libraries current. When a dependency has an input handling flaw, you inherit it. A dependency scan will show which packages in your project carry known issues, and reachability analysis helps you see whether your code actually calls the affected function. You can try the free in-browser scan at gold.safeguard.sh/scan. No login is needed, and the file stays on your machine, up to 100 dependencies.
Quick check
Why is CWE-20 called a class weakness?
It is a broad category above more specific ones. Path traversal and integer overflow, for example, often have missing or flawed validation as their root, so CWE-20 sits above them.
Why prefer an allow list to a deny list?
An allow list states what is valid and refuses everything else, including inputs you did not think of. A deny list only blocks what you thought to list.
Can fuzzing prove validation is complete?
No. It can reveal gaps, such as crashes or interpreter errors, but a clean run does not prove every property was checked. Pair it with review of the rules.