Unchecked Error Condition
Description
Unchecked Error Condition is a vulnerability that occurs when programmers fail to properly check or handle exceptions and error conditions. This weakness arises from flawed assumptions: either that an operation cannot fail, or that failures don't matter. When exceptions are ignored or error conditions go unchecked, attackers can induce unexpected behavior that goes unnoticed. The program continues execution in a potentially invalid state, unaware that a critical operation has failed.
Risk
Ignoring exceptions and error conditions allows attackers to exploit the gap between expected and actual system states. Memory allocation failures, file operations, network communications, and authentication checks that silently fail leave applications vulnerable. Security controls that are bypassed due to unchecked errors may grant unauthorized access. Data corruption can occur when operations fail midway without proper handling. The silent nature of these failures makes them particularly dangerous as there's no logged evidence of the problem, hindering detection and forensic analysis.
Solution
Select programming languages that enforce compile-time exception handling to catch these issues during development. Catch all relevant exceptions and ensure that all exceptions are handled in a way that maintains predictable system state. Never leave catch blocks empty - at minimum log the error for debugging. Establish coding standards that require explicit error handling. Use static analysis tools to detect unchecked error conditions. Document which exceptions each function can throw and require callers to handle them. Consider using languages with checked exceptions or linters that warn about ignored errors.
Common Consequences
| Impact | Details |
|---|---|
| Integrity | Scope: Integrity, Other Varies by Context - Unexpected State, Altered Execution Logic. The system may enter an invalid state leading to unintended behaviors. |
Example Code
Vulnerable Code
// Vulnerable: Exception caught but completely ignored
public class VulnerableExchange {
public void performExchange() {
try {
doExchange();
} catch (RareException e) {
// Vulnerable: "this can never happen"
// If it does happen, no one will ever know
}
// Continues as if exchange succeeded
confirmExchange();
}
public void processFile(String path) {
FileInputStream fis = null;
try {
fis = new FileInputStream(path);
processData(fis);
} catch (FileNotFoundException e) {
// Vulnerable: Silently ignored
} catch (IOException e) {
// Vulnerable: Also ignored
}
// May have processed no data at all
}
}
// Vulnerable: Return value not checked
void vulnerable_operation() {
char *data = malloc(1024);
// Vulnerable: malloc can return NULL
strcpy(data, get_user_input()); // Crash if NULL
FILE *f = fopen("/tmp/data", "w");
// Vulnerable: fopen can return NULL
fwrite(data, 1, strlen(data), f); // Crash if NULL
fclose(f);
}
// Vulnerable: Error code ignored
void vulnerable_network() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
// Vulnerable: socket can return -1
connect(sock, (struct sockaddr*)&addr, sizeof(addr));
// Vulnerable: connect can fail
send(sock, buffer, len, 0);
// Vulnerable: send can fail partially or completely
}
# Vulnerable: Bare except that ignores all errors
def vulnerable_database_operation():
try:
connection = database.connect()
cursor = connection.cursor()
cursor.execute("INSERT INTO audit_log VALUES (?)", (event,))
connection.commit()
except:
# Vulnerable: All exceptions silently swallowed
pass
# Continues as if logging succeeded
perform_sensitive_operation()
Fixed Code
// Fixed: Proper exception handling
public class SecureExchange {
public void performExchange() throws ExchangeException {
try {
doExchange();
} catch (RareException e) {
// Fixed: Log and handle or propagate
logger.error("Rare exception during exchange", e);
throw new ExchangeException("Exchange failed", e);
}
confirmExchange();
}
public void processFile(String path) throws FileProcessingException {
try (FileInputStream fis = new FileInputStream(path)) {
processData(fis);
} catch (FileNotFoundException e) {
// Fixed: Handle appropriately
logger.error("File not found: " + path, e);
throw new FileProcessingException("File not found: " + path, e);
} catch (IOException e) {
// Fixed: Handle I/O errors
logger.error("Error reading file: " + path, e);
throw new FileProcessingException("Failed to read file", e);
}
}
}
// Fixed: Check all return values
int secure_operation() {
char *data = malloc(1024);
// Fixed: Check malloc return
if (data == NULL) {
perror("malloc failed");
return -1;
}
const char *input = get_user_input();
if (input == NULL) {
free(data);
return -1;
}
strncpy(data, input, 1023);
data[1023] = '\0';
FILE *f = fopen("/tmp/data", "w");
// Fixed: Check fopen return
if (f == NULL) {
perror("fopen failed");
free(data);
return -1;
}
size_t written = fwrite(data, 1, strlen(data), f);
// Fixed: Check write success
if (written != strlen(data)) {
perror("fwrite incomplete");
fclose(f);
free(data);
return -1;
}
fclose(f);
free(data);
return 0;
}
// Fixed: Check network operations
int secure_network() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
// Fixed: Check socket creation
if (sock < 0) {
perror("socket failed");
return -1;
}
// Fixed: Check connect
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("connect failed");
close(sock);
return -1;
}
// Fixed: Check send
ssize_t sent = send(sock, buffer, len, 0);
if (sent < 0) {
perror("send failed");
close(sock);
return -1;
}
if (sent != len) {
fprintf(stderr, "Partial send: %zd of %zu\n", sent, len);
}
close(sock);
return 0;
}
# Fixed: Proper exception handling
def secure_database_operation():
try:
connection = database.connect()
cursor = connection.cursor()
cursor.execute("INSERT INTO audit_log VALUES (?)", (event,))
connection.commit()
except DatabaseError as e:
# Fixed: Log specific error
logger.error(f"Database operation failed: {e}")
# Fixed: Don't proceed if audit logging failed
raise AuditFailureException("Audit logging required") from e
finally:
if connection:
connection.close()
# Only proceed if logging succeeded
perform_sensitive_operation()
CVE Examples
No specific CVEs are listed for this CWE. The vulnerability pattern appears in:
- Applications with empty catch blocks
- C code that ignores function return values
- Systems that continue after security-critical operations fail
References
- MITRE Corporation. "CWE-391: Unchecked Error Condition." https://cwe.mitre.org/data/definitions/391.html