Weakness reference
CWE-252

Unchecked Return Value

This weakness occurs when code calls a function but ignores its return value, particularly when that return value indicates success or failure. Ignoring error…

01Summary

This weakness occurs when code calls a function but ignores its return value, particularly when that return value indicates success or failure. Ignoring error signals can cause the program to continue operating on invalid data, leading to crashes, data corruption, or security vulnerabilities. It's a common oversight that turns recoverable errors into silent failures.

02How It Happens

Many functions return a status code or result object to signal whether the operation succeeded. Common examples include file operations (open, read, write), network calls, authentication checks, and memory allocation. When a developer calls such a function but doesn't inspect the return value, the code assumes success and proceeds unconditionally. If the operation actually failed—due to permissions, network issues, resource exhaustion, or invalid input—the program operates on garbage data or incomplete state, leading to unpredictable behavior downstream.

This is especially dangerous in security-sensitive contexts: a failed authentication check that goes unnoticed, an unchecked file read that leaves a buffer uninitialized, or a failed encryption operation that silently uses plaintext instead.

03Real-World Impact

Unchecked return values can lead to authentication bypasses (if a login check's failure is ignored), information disclosure (reading uninitialized memory), denial of service (crashes from null pointer dereferences), or data integrity issues (writing incomplete or corrupted data). In some cases, an attacker can trigger a specific failure condition and exploit the resulting undefined behavior. The impact ranges from minor (a log file isn't written) to critical (a security check is silently skipped).

04Vulnerable & Fixed Patterns

Vulnerable pattern
import json

def load_config(filename):
    with open(filename) as f:
        config = json.load(f)
    return config

def authenticate_user(username, password):
    # Returns True on success, False on failure
    # (implementation omitted)
    return check_credentials(username, password)

# Vulnerable: return value ignored
authenticate_user(user_input, pass_input)
grant_admin_access()  # Proceeds regardless of auth result

Why it's vulnerable:
The authenticate_user() call returns a boolean indicating success or failure, but the code ignores it and grants access unconditionally. If authentication fails, the function still executes.

Fixed pattern
import json

def load_config(filename):
    with open(filename) as f:
        config = json.load(f)
    return config

def authenticate_user(username, password):
    return check_credentials(username, password)

# Fixed: return value checked
if authenticate_user(user_input, pass_input):
    grant_admin_access()
else:
    log_failed_auth(user_input)
    raise AuthenticationError("Invalid credentials")
Vulnerable pattern
<?php
function verify_token($token) {
    // Returns true if valid, false otherwise
    return hash_equals($expected_token, $token);
}

function save_file($filename, $data) {
    // Returns number of bytes written, or false on failure
    return file_put_contents($filename, $data);
}

// Vulnerable: return values ignored
verify_token($_POST['token']);
$_SESSION['user_id'] = $user_id;

save_file('/tmp/log.txt', $log_entry);
echo "Data saved";
?>

Why it's vulnerable:
Both verify_token() and save_file() return status indicators, but the code ignores them. The session is set even if the token is invalid, and the success message is printed even if the file write failed.

Fixed pattern
<?php
function verify_token($token) {
    return hash_equals($expected_token, $token);
}

function save_file($filename, $data) {
    return file_put_contents($filename, $data);
}

// Fixed: return values checked
if (!verify_token($_POST['token'])) {
    http_response_code(403);
    die("Invalid token");
}
$_SESSION['user_id'] = $user_id;

if (save_file('/tmp/log.txt', $log_entry) === false) {
    error_log("Failed to write log file");
    http_response_code(500);
    die("Internal error");
}
echo "Data saved";
?>

05Prevention Checklist

Enable compiler/linter warnings:
Use -Wall -Wextra (C/C++), pylint, phpstan, or similar tools configured to flag unused return values.
Mark critical functions with attributes:
Use [[nodiscard]] (C++17+), @must_use (Rust), or similar annotations to force explicit handling of return values.
Check return values at security boundaries:
Always inspect results from authentication, authorization, encryption, and file I/O operations.
Use exceptions or error objects:
Prefer raising exceptions or returning structured error objects over silent boolean flags, making failures harder to ignore.
Code review for error handling:
During review, specifically ask: "What does this function return, and what does the caller do with it?"
Test failure paths:
Write unit tests that simulate function failures (file not found, network timeout, permission denied) and verify the caller handles them correctly.

06Signs You May Already Be Affected

Look for functions that perform security checks or I/O operations but whose return values are never assigned or tested. Search your codebase for patterns like function_call(); on a line by itself (especially for file operations, authentication, or encryption). Check logs for unexpected crashes or "null pointer" errors that occur after operations that should have failed gracefully. If a security check or file operation is followed immediately by code that assumes success, the return value is likely being ignored.

07Related Recent Vulnerabilities