CWE-478, Missing Default Case in Multiple Condition Expression, covers a switch statement, or similar construct with many branches, that has no default case while not handling every value that can occur. MITRE lists C, C++, Java, C#, Python and JavaScript.
When a value falls through every branch, nothing happens, and the program continues with variables in whatever state they were in.
How it happens
// Vulnerable: an unknown role is silently ignored
int perms = 0;
switch (role) {
case ROLE_ADMIN: perms = ALL; break;
case ROLE_EDITOR: perms = EDIT; break;
case ROLE_VIEWER: perms = READ; break;
}
grant(user, perms);
If a new role is added to the enum and this switch is not updated, or an attacker supplies an unexpected value, perms stays at zero here. That is the safe outcome in this example. Flip the initial value, or use a variable that was set earlier by something else, and the same gap grants access.
MITRE describes the pattern as one where later decisions are made on poor information, producing a cascade of failures that can lead to any number of security issues. It also warns about a common false fix: a default case that simply stands for an assumed option instead of checking for invalid input is poor practice, and in some cases as bad as having no default at all.
What an attacker gains
The record lists altered execution logic, and says the consequences depend on the circumstances. They can touch confidentiality, authentication, authorization, availability, integrity, accountability or non repudiation.
How to find it
Static analysis can find some instances. Many compilers also warn about unhandled enum values in a switch. Turn those warnings on. The record lists no observed CVEs for this entry.
How to fix it
Make sure no case is left unaccounted for when program flow or values depend on a variable. Add a default case, and have it do something deliberate with bad input.
switch (role) {
case ROLE_ADMIN: perms = ALL; break;
case ROLE_EDITOR: perms = EDIT; break;
case ROLE_VIEWER: perms = READ; break;
default:
log_error("unknown role %d", role);
return DENIED; /* fail closed */
}
The default here is not an assumed option. It rejects and records the unexpected value.
Quick check
Is a default that picks the most common option fine?
No. MITRE calls that poor practice. A default should detect invalid input and fail safely, not guess.