This weakness occurs when software fails to implement a feature, security control, or behavior exactly as it was designed or specified to work. The gap between…
This weakness occurs when software fails to implement a feature, security control, or behavior exactly as it was designed or specified to work. The gap between what was promised and what actually happens can introduce security flaws—sometimes subtle ones that slip past initial testing. Unlike a bug that crashes the program, this is a logic flaw where the code runs without error but does the wrong thing from a security perspective.
02How It Happens
Developers write code based on a specification or design document, but misinterpret the requirements, skip a step, or implement only part of the intended logic. This can happen because:
- A specification is ambiguous or poorly communicated, and the developer makes a reasonable but incorrect assumption.
- A security control is documented but the implementation omits a critical check or validation step.
- A feature is partially implemented—the happy path works, but edge cases or error conditions are not handled as specified.
- Code is refactored or simplified without verifying that all original security properties are preserved.
The result is code that appears to work in normal use but fails to enforce a security boundary, validate input correctly, or protect sensitive data as intended.
03Real-World Impact
Depending on what functionality is missing or wrong, the consequences can range from minor to severe. An authentication system might fail to enforce multi-factor authentication on sensitive operations. A permission check might be skipped in one code path, allowing unauthorized access. A data sanitization routine might be incomplete, leaving some inputs unfiltered. These gaps often go unnoticed until an attacker or security researcher specifically tests the boundary condition that the specification intended to protect.
04Vulnerable & Fixed Patterns
Vulnerable pattern
# Specification: "All user input must be validated against a whitelist of allowed characters."
def process_username(user_input):
# Developer implements only a partial check
if len(user_input) > 0:
return user_input.lower()
return None
# The function runs without error, but does not enforce the whitelist.
# An attacker can pass special characters that the spec forbade.
Why it's vulnerable: The code implements length validation but omits the character whitelist check that the specification required. The function appears to work but does not fulfill the security requirement.
Fixed pattern
import re
def process_username(user_input):
# Specification: "Only alphanumeric characters and underscores allowed."
allowed_pattern = r'^[a-zA-Z0-9_]+$'
if not user_input or not re.match(allowed_pattern, user_input):
raise ValueError("Username contains invalid characters")
return user_input.lower()
Vulnerable pattern
<?php
// Specification: "Admin actions require both password and security token verification."
function delete_user($user_id, $password) {
if (verify_password($password)) {
// Developer forgot to check the security token
delete_from_database($user_id);
return true;
}
return false;
}
Why it's vulnerable: The function implements password verification but omits the security token check specified in the design. An attacker who knows the password can bypass the intended two-factor protection.
Fixed pattern
<?php
// Specification: "Admin actions require both password and security token verification."
function delete_user($user_id, $password, $token) {
if (!verify_password($password)) {
return false;
}
if (!verify_csrf_token($token)) {
return false;
}
delete_from_database($user_id);
return true;
}
05Prevention Checklist
Document security requirements explicitly. Write specifications that name every security control, validation rule, and error condition. Use checklists or acceptance criteria tied to each requirement.
Review code against the specification. Before merging, verify that the implementation covers every point in the design—not just the happy path.
Test edge cases and error conditions. Automated tests should verify that security controls work when input is invalid, missing, or malicious, not just when it is well-formed.
Use code review and threat modeling. Have a second person review security-critical code and ask: "Does this do what the spec says it should do?"
Maintain a traceability matrix. Map each security requirement to the code that implements it, so gaps are visible.
Automate compliance checks where possible. Use linters, type checkers, or custom rules to flag missing validations or incomplete implementations.
06Signs You May Already Be Affected
Look for discrepancies between your documented security design and what the code actually does. This might appear as security controls that work in some code paths but not others, or features that pass basic testing but fail under unusual input. Review your security incident logs and penetration test reports for findings that mention "missing validation" or "incomplete implementation"—these often point to this class of weakness.