Always-Incorrect Control Flow Implementation

Description

Always-Incorrect Control Flow Implementation occurs when code contains logic that will always produce incorrect behavior regardless of input or program state. This includes impossible conditions, unreachable code paths, conditions that can never be true/false, and logic errors that make security checks ineffective. Unlike conditional bugs that only trigger under certain circumstances, these flaws are fundamentally broken in all cases.

Risk

Security checks that never execute. Authentication bypass when conditions are inverted. Authorization always granted or denied incorrectly. Critical code paths never reached. Error handling that never triggers. Validation that always passes or fails regardless of input.

Solution

Use static analysis to detect dead code and impossible conditions. Review control flow for logical correctness. Test both positive and negative paths. Use code coverage to find unreachable code. Implement proper boolean logic in security checks. Review comparisons for type mismatches.

Common Consequences

ImpactDetails
AuthorizationScope: Complete Bypass

Security checks always fail or succeed.
IntegrityScope: Logic Errors

Code never behaves as intended.
AvailabilityScope: Functionality Broken

Expected features never work.

Example Code + Solution Code

Vulnerable Code

// VULNERABLE: Always-incorrect control flow in C
#include <stdio.h>
#include <string.h>

// VULNERABLE: Condition is always true
int check_auth_vulnerable1(char* password) {
    // VULNERABLE: Assignment instead of comparison
    if (password = "secret") {  // Always true (non-null pointer)
        return 1;  // Always authenticated!
    }
    return 0;  // Never reached
}

// VULNERABLE: Condition is always false
int check_auth_vulnerable2(char* password) {
    // VULNERABLE: Comparing pointers, not strings
    if (password == "secret") {  // Almost always false
        return 1;  // Never reached unless same literal
    }
    return 0;  // Always returned
}

// VULNERABLE: Unsigned comparison always true
int validate_index_vulnerable(unsigned int index) {
    // VULNERABLE: Unsigned is always >= 0
    if (index >= 0) {  // Always true
        return 1;  // Always valid!
    }
    return 0;  // Never reached
}

// VULNERABLE: Logic error with return
int process_vulnerable(int value) {
    if (value > 0) {
        return 1;
    }

    // VULNERABLE: Early return makes this unreachable
    return 0;

    // This security check never executes
    if (!validate_value(value)) {
        log_error("Invalid value");
        return -1;
    }
}

// VULNERABLE: Semicolon after if
void security_check_vulnerable(int user_level) {
    if (user_level < ADMIN_LEVEL);  // VULNERABLE: Semicolon!
    {
        // This block always executes
        grant_admin_access();
    }
}

// VULNERABLE: Bitwise vs logical operator
int check_permissions_vulnerable(int perm1, int perm2) {
    // VULNERABLE: & instead of &&
    if (perm1 & perm2) {  // Bitwise AND, not logical
        // May not work as expected
        return 1;
    }
    return 0;
}
# VULNERABLE: Python always-incorrect control flow
class VulnerableAuth:

    # VULNERABLE: Always True condition
    def check_password_vulnerable1(self, password):
        # VULNERABLE: 'is' compares identity, not equality
        # String literals may or may not be interned
        if password is "secret":  # Usually False
            return True
        return False  # Almost always returned

    # VULNERABLE: Wrong return placement
    def validate_vulnerable(self, data):
        return True  # VULNERABLE: Always returns True first

        # This validation never runs
        if not self.is_valid(data):
            raise ValueError("Invalid data")

    # VULNERABLE: Empty condition block
    def process_vulnerable(self, value):
        if value < 0:
            pass  # VULNERABLE: Does nothing
            # Negative values not handled!

        self.process_value(value)  # Processes negative values

    # VULNERABLE: Mutable default argument
    def add_permission_vulnerable(self, perm, perms=[]):
        # VULNERABLE: perms shared between all calls
        perms.append(perm)
        return perms  # Accumulates across calls!

    # VULNERABLE: Boolean short-circuit mistake
    def check_access_vulnerable(self, user, resource):
        # VULNERABLE: Second condition never evaluated if first is True
        if True or self.has_permission(user, resource):
            return True
        return False

# VULNERABLE: Exception handling that catches everything
def process_request_vulnerable(request):
    try:
        result = dangerous_operation(request)
    except:  # VULNERABLE: Catches all exceptions
        pass  # VULNERABLE: Silently ignores errors
    return result  # May be undefined!
// VULNERABLE: Java always-incorrect control flow
public class VulnerableControlFlow {

    // VULNERABLE: String comparison with ==
    public boolean checkPassword(String password) {
        // VULNERABLE: == compares references, not content
        if (password == "secret") {  // Usually false
            return true;  // Rarely reached
        }
        return false;
    }

    // VULNERABLE: Always-false due to null check order
    public boolean validateUser(User user) {
        // VULNERABLE: user.getRole() called before null check
        if (user.getRole().equals("admin") && user != null) {
            return true;  // NPE if user is null
        }
        return false;
    }

    // VULNERABLE: Unreachable code
    public int calculate(int value) {
        if (value > 0) {
            return value * 2;
        } else {
            return value * -1;
        }

        // VULNERABLE: Never reached
        if (isSpecialValue(value)) {
            return handleSpecial(value);
        }
    }

    // VULNERABLE: Boolean literal comparison
    public boolean isActive(boolean flag) {
        // VULNERABLE: Redundant and error-prone
        if (flag == true) {  // Works but could be == false by mistake
            return true;
        }
        return false;
    }

    // VULNERABLE: instanceof with wrong type
    public void process(Object obj) {
        // VULNERABLE: Always false if obj can never be String here
        if (obj instanceof Integer && obj instanceof String) {  // Impossible
            // Never executed
            handleSpecial(obj);
        }
    }

    // VULNERABLE: Inverted condition
    public void securityCheck(User user, Resource resource) {
        // VULNERABLE: ! negates entire expression when only want first part
        if (!user.isAuthenticated() && user.hasPermission(resource)) {
            // Intended: authenticated AND has permission
            // Actual: NOT authenticated AND has permission
            grantAccess(resource);  // Wrong users get access
        }
    }
}
// VULNERABLE: JavaScript always-incorrect control flow
class VulnerableAuth {

    // VULNERABLE: Type coercion issues
    checkAuth(input) {
        // VULNERABLE: '==' performs type coercion
        if (input == true) {  // "1" == true is true
            return true;  // Unintended truthy values pass
        }

        // Also vulnerable: '' == false, 0 == false, etc.
        return false;
    }

    // VULNERABLE: Assignment in condition
    checkAdmin(role) {
        // VULNERABLE: Single = is assignment
        if (role = 'admin') {  // Always truthy (non-empty string)
            return true;  // Everyone is admin!
        }
        return false;
    }

    // VULNERABLE: Array/Object truthiness
    checkPermissions(perms) {
        // VULNERABLE: Empty array is truthy
        if (perms) {  // [] is truthy!
            return true;  // Empty permissions still passes
        }
        return false;
    }

    // VULNERABLE: typeof comparison error
    validateInput(value) {
        // VULNERABLE: typeof returns string, comparing to undefined fails
        if (typeof value === undefined) {  // Always false
            return false;  // Never reached
        }
        // Should be: typeof value === 'undefined'
        return true;  // Everything passes
    }

    // VULNERABLE: NaN comparison
    validateNumber(num) {
        // VULNERABLE: NaN !== NaN
        if (num !== NaN) {  // Always true (even for NaN!)
            return true;  // NaN passes validation
        }
        return false;
    }

    // VULNERABLE: Floating point comparison
    checkBalance(amount, required) {
        // VULNERABLE: Floating point precision issues
        if (0.1 + 0.2 === 0.3) {  // False! (0.30000000000000004)
            // This code never executes
            return amount >= required;
        }
        return false;  // Always returned
    }
}

// VULNERABLE: Hoisting issues
function processVulnerable(value) {
    if (value > 0) {
        return process(value);
    }

    // VULNERABLE: Variable hoisting makes this undefined, not error
    return result;  // Always undefined

    var result = calculate(value);  // Never executed
}

Fixed Code

// SAFE: Correct control flow in C
#include <stdio.h>
#include <string.h>

// SAFE: Proper comparison
int check_auth_safe1(const char* password) {
    // SAFE: strcmp for string comparison
    if (strcmp(password, "secret") == 0) {
        return 1;
    }
    return 0;
}

// Alternative: Use == with constant on left (Yoda condition)
int check_auth_safe2(const char* password) {
    // Compiler error if = used instead of ==
    if (NULL == password) {
        return 0;
    }
    return strcmp(password, "secret") == 0;
}

// SAFE: Proper bounds checking
int validate_index_safe(int index, int max_size) {
    // SAFE: Signed integer properly checked
    if (index >= 0 && index < max_size) {
        return 1;
    }
    return 0;
}

// SAFE: Proper control flow order
int process_safe(int value) {
    // Validation first
    if (!validate_value(value)) {
        log_error("Invalid value");
        return -1;
    }

    if (value > 0) {
        return 1;
    }

    return 0;
}

// SAFE: No semicolon after if
void security_check_safe(int user_level) {
    if (user_level >= ADMIN_LEVEL) {
        grant_admin_access();
    }
}

// SAFE: Logical operators
int check_permissions_safe(int has_perm1, int has_perm2) {
    // SAFE: Logical AND
    if (has_perm1 && has_perm2) {
        return 1;
    }
    return 0;
}
# SAFE: Python correct control flow
class SafeAuth:

    # SAFE: Proper string comparison
    def check_password_safe(self, password):
        # SAFE: == compares values
        if password == "secret":
            return True
        return False

    # SAFE: Correct return placement
    def validate_safe(self, data):
        # Validation runs first
        if not self.is_valid(data):
            raise ValueError("Invalid data")

        return True  # Only after validation

    # SAFE: Proper negative handling
    def process_safe(self, value):
        if value < 0:
            raise ValueError("Negative value not allowed")

        self.process_value(value)

    # SAFE: No mutable default argument
    def add_permission_safe(self, perm, perms=None):
        if perms is None:
            perms = []  # New list each call
        perms.append(perm)
        return perms

    # SAFE: Proper boolean logic
    def check_access_safe(self, user, resource):
        if self.has_permission(user, resource):
            return True
        return False

# SAFE: Specific exception handling
def process_request_safe(request):
    try:
        result = operation(request)
        return result
    except ValidationError as e:
        log_error(f"Validation failed: {e}")
        return None
    except OperationError as e:
        log_error(f"Operation failed: {e}")
        raise
// SAFE: Java correct control flow
public class SafeControlFlow {

    // SAFE: equals() for string comparison
    public boolean checkPassword(String password) {
        if ("secret".equals(password)) {  // Also null-safe
            return true;
        }
        return false;
    }

    // SAFE: Null check first
    public boolean validateUser(User user) {
        if (user != null && "admin".equals(user.getRole())) {
            return true;
        }
        return false;
    }

    // SAFE: All paths reachable
    public int calculate(int value) {
        if (isSpecialValue(value)) {
            return handleSpecial(value);
        }

        if (value > 0) {
            return value * 2;
        } else {
            return value * -1;
        }
    }

    // SAFE: Direct boolean usage
    public boolean isActive(boolean flag) {
        return flag;  // No comparison needed
    }

    // SAFE: Logical instanceof checks
    public void process(Object obj) {
        if (obj instanceof Integer) {
            handleInteger((Integer) obj);
        } else if (obj instanceof String) {
            handleString((String) obj);
        }
    }

    // SAFE: Clear boolean logic
    public void securityCheck(User user, Resource resource) {
        // SAFE: Parentheses make intent clear
        if (user.isAuthenticated() && user.hasPermission(resource)) {
            grantAccess(resource);
        }
    }
}
// SAFE: JavaScript correct control flow
class SafeAuth {

    // SAFE: Strict equality
    checkAuth(input) {
        if (input === true) {  // Only actual true passes
            return true;
        }
        return false;
    }

    // SAFE: Proper comparison
    checkAdmin(role) {
        if (role === 'admin') {  // Correct comparison
            return true;
        }
        return false;
    }

    // SAFE: Check array length
    checkPermissions(perms) {
        if (Array.isArray(perms) && perms.length > 0) {
            return true;
        }
        return false;
    }

    // SAFE: Correct typeof usage
    validateInput(value) {
        if (typeof value === 'undefined') {  // String comparison
            return false;
        }
        return true;
    }

    // SAFE: NaN check using Number.isNaN
    validateNumber(num) {
        if (Number.isNaN(num)) {
            return false;  // Properly detects NaN
        }
        return true;
    }

    // SAFE: Epsilon comparison for floats
    checkBalance(amount, required) {
        const epsilon = 0.0001;
        const sum = 0.1 + 0.2;
        if (Math.abs(sum - 0.3) < epsilon) {
            return amount >= required;
        }
        return false;
    }
}

// SAFE: Proper variable declaration
function processSafe(value) {
    if (value > 0) {
        return process(value);
    }

    // Use let/const to avoid hoisting issues
    const result = calculate(value);
    return result;
}

// SAFE: Using linter rules
// eslint: eqeqeq, no-cond-assign, no-unreachable

Exploited in the Wild

Authentication Bypass

Inverted conditions granting access to everyone.

Authorization Failures

Security checks that never execute.

Logic Bombs

Unreachable code containing backdoors.


Tools to test/exploit

  • Static analyzers (dead code detection).

  • Linters (eslint, pylint, checkstyle).

  • Compiler warnings (-Wall).


CVE Examples

  • Various CVEs from logic errors in authentication.

  • Security bypass from inverted conditions.


References

  1. MITRE. "CWE-670: Always-Incorrect Control Flow Implementation." https://cwe.mitre.org/data/definitions/670.html

  2. Static analysis best practices.