Skip to content

CWE-665: Improper Initialization

Overview

Improper initialization occurs when variables, objects, or resources aren't properly initialized before use, leading to undefined behavior, use of garbage values, null pointer dereferences, weak crypto (uninitialized RNG), and security check bypasses.

Risk

Medium-High: Uninitialized data causes information disclosure (memory leaks), weak cryptography (unseeded RNG), authentication bypass (uninitialized flags), crashes (null pointers), and unpredictable behavior exploitable by attackers.

Remediation Steps

Core principle: Initialize variables/state securely before use; uninitialized or partial initialization must not influence security decisions.

Locate the uninitialized variable or object

  • Review the security scan results to identify the specific file, line number, and variable
  • Identify what is uninitialized: primitive variable, object field, array/buffer, cryptographic state
  • Trace the data flow: where is the uninitialized value read or used
  • Determine the impact: authentication bypass, weak crypto, information disclosure, crash

Initialize all variables at declaration (Primary Defense)

  • Set safe default values: Initialize all variables when declared
  • For security flags, default to false/denied: int authenticated = 0;, boolean isAdmin = false;
  • For pointers, initialize to NULL: char *ptr = NULL;
  • For objects, initialize all fields: Set safe defaults in constructors
  • Example (C): int authenticated = 0; instead of int authenticated;
  • Example (Java): private String role = "USER"; instead of private String role;
  • Why this works: Eliminates undefined behavior and ensures safe defaults

Initialize arrays and buffers to zero

  • Zero-initialize buffers: char buffer[1024] = {0};
  • Use memset for large buffers: memset(buffer, 0, sizeof(buffer));
  • Initialize arrays: int arr[10] = {0};
  • For dynamic allocations: Use calloc() instead of malloc() (calloc zeros memory)
  • Prevents: Information disclosure from memory leaks, unpredictable behavior

Initialize cryptographic components properly

  • Use cryptographically secure RNG: secrets module (Python), SecureRandom (Java), /dev/urandom (C)
  • Don't use unseeded random: Avoid random.randint() (Python), rand() (C), Math.random() (Java) for security
  • Initialize crypto libraries: Call initialization functions (OpenSSL_init, crypto library setup)
  • Example (Python): import secrets; token = secrets.randbelow(1000000)
  • Example (Java): SecureRandom sr = new SecureRandom(); int token = sr.nextInt(1000000);

Add initialization verification and defensive checks

  • Check for null/uninitialized before use: if (ptr == NULL) return error;
  • Run Static Analysis tools regularly as part of your SDLC
  • Enable compiler warnings: -Wuninitialized (GCC), /W4 (MSVC)
  • Review all paths ensure variables initialized before use

Test the initialization fix thoroughly

  • Test all code paths ensure variables properly initialized
  • Test edge cases where initialization might be skipped
  • Use memory sanitizers (Valgrind, AddressSanitizer) to detect uninitialized reads
  • Verify security flags default to safe values
  • Re-scan with security scanner to confirm the issue is resolved

Common Initialization Issues

Uninitialized Variables:

int status;  // Garbage value
if (error_occurred) {
    status = -1;
}
return status;  // May return garbage!

Uninitialized Pointers:

char *ptr;  // Dangling pointer
if (condition) {
    ptr = malloc(100);
}
strcpy(ptr, data);  // Crash if condition false!

Uninitialized Security Flags:

boolean isVerified;
if (checkSignature()) {
    isVerified = true;
}
if (isVerified) {  // May skip signature check!
    process();
}

Uninitialized Crypto State:

class Encryptor:
    def __init__(self):
        pass  // iv not initialized!

    def encrypt(self, data):
        return AES.new(self.key, AES.MODE_CBC, self.iv).encrypt(data)
        // iv is None - error or weak crypto

Secure Initialization Patterns

// C++ - use constructors
class SecureSession {
private:
    bool authenticated;
    string user_id;
    time_t created_at;

public:
    SecureSession() 
        : authenticated(false),  // Member initializer list
          user_id(""),
          created_at(time(nullptr))
    {
        // All members initialized
    }
};

// RAII pattern
class DatabaseConnection {
public:
    DatabaseConnection(const string& dsn) {
        conn = connect(dsn);
        if (!conn) {
            throw ConnectionError("Failed to connect");
        }
    }

    ~DatabaseConnection() {
        if (conn) disconnect(conn);
    }
};
# Python - use __init__

class User:
    def __init__(self, username):
        self.username = username
        self.role = 'user'  # Safe default
        self.is_active = False
        self.permissions = set()  # Empty set
        self.created_at = datetime.now()
// Java - initialize at declaration
public class Configuration {
    private int maxConnections = 100;  // Default
    private String dbHost = "localhost";
    private boolean enableCache = true;
    private List<String> allowedIPs = new ArrayList<>();

    public Configuration() {
        // Fields already initialized
    }
}

Additional Resources