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 ofint authenticated; - Example (Java):
private String role = "USER";instead ofprivate 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 ofmalloc()(calloc zeros memory) - Prevents: Information disclosure from memory leaks, unpredictable behavior
Initialize cryptographic components properly
- Use cryptographically secure RNG:
secretsmodule (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
}
}