Creation of Class Instance within a Static Code Block

Description

Creation of Class Instance within a Static Code Block occurs when a product contains a static code block that creates a class instance, either directly or indirectly. Static initializers run when the class is loaded, which happens once per classloader and at an unpredictable time. Creating instances in static blocks can lead to initialization order problems, resource leaks, exception handling difficulties, and testing challenges. The instance is created before the application is fully initialized, potentially leading to incomplete configuration or missing dependencies.

Risk

This pattern creates reliability and potential security risks. Exceptions thrown during static initialization cause ExceptionInInitializerError, which is difficult to handle and debug. Resources allocated in static blocks may never be properly released. The unpredictable timing of class loading can cause race conditions. Security-sensitive initialization might occur before security context is established. Configuration or dependencies may not be available during static initialization. Static instances are difficult to mock for security testing, potentially leaving security paths untested. Memory leaks can occur if the static instance holds references that prevent garbage collection.

Solution

Use lazy initialization instead of static blocks. Apply the singleton pattern with proper lazy initialization (double-checked locking, initialization-on-demand holder, or enum singleton). Use dependency injection frameworks to manage instance lifecycle. Defer initialization until the application context is fully established. If static initialization is necessary, keep it simple and handle exceptions properly. Consider using factory patterns for instance creation. For testing, design classes to allow dependency injection rather than creating instances in static contexts.

Common Consequences

ImpactDetails
OtherScope: Other

Reduce Reliability - Static initialization failures cause hard-to-debug class loading errors.
OtherScope: Other

Reduce Maintainability - Static instances are difficult to test and mock.
AvailabilityScope: Availability

DoS: Resource Consumption - Resources allocated in static blocks may leak if not properly managed.

Example Code

Vulnerable Code

// Vulnerable: Creating instances in static initializer
public class VulnerableConfiguration {

    // Vulnerable: Instance created during class loading
    private static final DatabaseConnection dbConnection;
    private static final ConfigurationLoader configLoader;
    private static final SecurityManager securityManager;

    static {
        // Vulnerable: All of these can fail during class loading
        try {
            // Database might not be available yet
            dbConnection = new DatabaseConnection("jdbc:mysql://localhost/db");

            // Config file might not be accessible
            configLoader = new ConfigurationLoader("/etc/app/config.xml");

            // Security context might not be established
            securityManager = new SecurityManager(configLoader.getSecuritySettings());

        } catch (Exception e) {
            // This exception wraps into ExceptionInInitializerError
            // and makes the class unusable
            throw new RuntimeException("Failed to initialize", e);
        }
    }

    public static DatabaseConnection getDatabase() {
        return dbConnection;  // Returns null if initialization failed partially
    }
}

// Problems:
// 1. If database is down at startup, class cannot be loaded
// 2. Partial initialization leaves system in inconsistent state
// 3. Cannot retry initialization after failure
// 4. Cannot mock for testing
# Vulnerable: Creating instances at module import time
# config.py

# Vulnerable: These execute when module is imported
_database = None
_config = None

# Vulnerable: Module-level initialization
try:
    # Executes during import - before app is ready
    _config = ConfigurationLoader('/etc/app/config.yaml')

    # Database credentials might not be available yet
    _database = DatabaseConnection(
        host=_config.get('db_host'),
        password=_config.get('db_password')  # Might be None!
    )
except Exception as e:
    # Module import fails entirely
    print(f"Failed to initialize: {e}")
    # But _database and _config might be partially set


class VulnerableService:
    # Vulnerable: Class attribute initialized at import time
    _instance = None
    _cache = HeavyCache(size_mb=100)  # 100MB allocated at import!

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance


# Just importing this module:
# 1. Tries to connect to database
# 2. Allocates 100MB for cache
# 3. Might fail and leave module in bad state
// Vulnerable: Static constructor with instance creation
public class VulnerableLogger
{
    // Vulnerable: Static field with inline initialization
    private static readonly FileStream logFile =
        new FileStream("/var/log/app.log", FileMode.Append);

    private static readonly VulnerableLogger instance;
    private static readonly object lockObj = new object();

    // Vulnerable: Static constructor
    static VulnerableLogger()
    {
        // If this fails, class becomes permanently unusable
        try
        {
            // External service might not be available
            var config = RemoteConfigService.FetchConfig();

            instance = new VulnerableLogger(config);

            // Resource allocated but might not be released
            var networkStream = new NetworkStream(
                new TcpClient(config.LogServer, config.LogPort).GetStream()
            );
        }
        catch (Exception ex)
        {
            // TypeInitializationException will be thrown on any access
            throw new InvalidOperationException("Logger initialization failed", ex);
        }
    }

    public static void Log(string message)
    {
        // Will throw TypeInitializationException if static ctor failed
        instance.WriteLog(message);
    }
}
// Vulnerable: C++ static initialization order fiasco
// file1.cpp
class VulnerableGlobalConfig {
public:
    static VulnerableGlobalConfig& getInstance() {
        // Vulnerable: Static local variable
        static VulnerableGlobalConfig instance;
        return instance;
    }

    std::string getValue(const std::string& key) {
        return config_[key];
    }

private:
    VulnerableGlobalConfig() {
        // Vulnerable: Uses another static that might not be initialized
        auto& logger = VulnerableLogger::getInstance();
        logger.log("Loading config...");

        // Load configuration...
    }

    std::map<std::string, std::string> config_;
};

// file2.cpp
class VulnerableLogger {
public:
    static VulnerableLogger& getInstance() {
        static VulnerableLogger instance;
        return instance;
    }

    void log(const std::string& msg) {
        // Vulnerable: Uses config that might not be initialized
        auto& config = VulnerableGlobalConfig::getInstance();
        std::string level = config.getValue("log_level");  // Circular!
        // ...
    }
};

// Static initialization order between translation units is undefined!

Fixed Code

// Fixed: Lazy initialization with proper lifecycle management
public class FixedConfiguration {

    // Fixed: No static instance creation
    private static volatile FixedConfiguration instance;

    private final DatabaseConnection dbConnection;
    private final ConfigurationLoader configLoader;
    private final SecurityManager securityManager;

    // Fixed: Private constructor - controlled initialization
    private FixedConfiguration(ConfigurationLoader config) throws ConfigurationException {
        this.configLoader = config;
        this.dbConnection = createDatabaseConnection(config);
        this.securityManager = createSecurityManager(config);
    }

    // Fixed: Lazy initialization with double-checked locking
    public static FixedConfiguration getInstance() throws ConfigurationException {
        if (instance == null) {
            synchronized (FixedConfiguration.class) {
                if (instance == null) {
                    // Load configuration only when needed
                    ConfigurationLoader config = new ConfigurationLoader(
                        System.getProperty("config.path", "/etc/app/config.xml")
                    );
                    instance = new FixedConfiguration(config);
                }
            }
        }
        return instance;
    }

    // Fixed: Alternative - Initialization-on-demand holder idiom
    private static class Holder {
        // Only created when Holder class is accessed
        static final FixedConfiguration INSTANCE = createInstance();

        private static FixedConfiguration createInstance() {
            try {
                ConfigurationLoader config = new ConfigurationLoader(
                    System.getProperty("config.path")
                );
                return new FixedConfiguration(config);
            } catch (Exception e) {
                throw new IllegalStateException("Configuration failed", e);
            }
        }
    }

    public static FixedConfiguration getInstanceLazy() {
        return Holder.INSTANCE;
    }

    // Fixed: Allow injection for testing
    public static void setInstance(FixedConfiguration testInstance) {
        instance = testInstance;
    }

    private DatabaseConnection createDatabaseConnection(ConfigurationLoader config)
            throws ConfigurationException {
        // Can properly handle failures and retry
        return new DatabaseConnection(config.getDatabaseUrl());
    }

    private SecurityManager createSecurityManager(ConfigurationLoader config)
            throws ConfigurationException {
        return new SecurityManager(config.getSecuritySettings());
    }
}
# Fixed: Lazy initialization with proper lifecycle
from functools import lru_cache
from threading import Lock
from typing import Optional


class FixedConfiguration:
    """Configuration with lazy initialization"""

    _instance: Optional['FixedConfiguration'] = None
    _lock = Lock()

    def __init__(self, config_path: str):
        # Fixed: Constructor can be called when ready
        self._config_path = config_path
        self._loaded = False
        self._config_data = None

    def _ensure_loaded(self):
        """Lazy load configuration on first access"""
        if not self._loaded:
            self._config_data = self._load_config()
            self._loaded = True

    def _load_config(self):
        # Load configuration - called only when needed
        import yaml
        with open(self._config_path) as f:
            return yaml.safe_load(f)

    @classmethod
    def get_instance(cls, config_path: str = '/etc/app/config.yaml') -> 'FixedConfiguration':
        """Thread-safe lazy singleton"""
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = cls(config_path)
        return cls._instance

    @classmethod
    def reset_instance(cls):
        """Allow resetting for testing"""
        with cls._lock:
            cls._instance = None


class FixedService:
    """Service with dependency injection"""

    def __init__(self, config: FixedConfiguration, cache: Optional['Cache'] = None):
        # Fixed: Dependencies injected, not created statically
        self._config = config
        self._cache = cache or self._create_default_cache()

    def _create_default_cache(self) -> 'Cache':
        # Fixed: Cache created lazily when service is instantiated
        cache_size = self._config.get('cache_size_mb', 10)
        return Cache(size_mb=cache_size)


# Fixed: Factory function for controlled initialization
def create_service(config_path: str = '/etc/app/config.yaml') -> FixedService:
    """Factory function - creates service when called, not at import"""
    config = FixedConfiguration.get_instance(config_path)
    return FixedService(config)
// Fixed: Lazy initialization with proper resource management
public sealed class FixedLogger : IDisposable
{
    private static readonly Lazy<FixedLogger> lazyInstance =
        new Lazy<FixedLogger>(() => CreateInstance(), LazyThreadSafetyMode.ExecutionAndPublication);

    private readonly StreamWriter logWriter;
    private readonly object writeLock = new object();
    private bool disposed = false;

    // Fixed: Private constructor
    private FixedLogger(StreamWriter writer)
    {
        this.logWriter = writer;
    }

    // Fixed: Lazy initialization with proper error handling
    private static FixedLogger CreateInstance()
    {
        try
        {
            var logPath = Environment.GetEnvironmentVariable("LOG_PATH") ?? "/var/log/app.log";
            var writer = new StreamWriter(logPath, append: true);
            return new FixedLogger(writer);
        }
        catch (Exception ex)
        {
            // Return a null logger instead of failing class loading
            Console.Error.WriteLine($"Logger initialization failed: {ex.Message}");
            return new FixedLogger(StreamWriter.Null);
        }
    }

    // Fixed: Instance only created when first accessed
    public static FixedLogger Instance => lazyInstance.Value;

    public void Log(string message)
    {
        if (disposed) return;

        lock (writeLock)
        {
            logWriter.WriteLine($"{DateTime.UtcNow:O}: {message}");
            logWriter.Flush();
        }
    }

    // Fixed: Proper resource cleanup
    public void Dispose()
    {
        if (!disposed)
        {
            disposed = true;
            logWriter?.Dispose();
        }
    }
}
// Fixed: C++ with proper initialization order
#include <memory>
#include <mutex>
#include <functional>

// Fixed: Use Meyers' Singleton with controlled initialization
class FixedConfig {
public:
    // Fixed: Returns reference, initialization order controlled
    static FixedConfig& getInstance() {
        static FixedConfig instance;
        return instance;
    }

    void initialize(const std::string& configPath) {
        std::lock_guard<std::mutex> lock(initMutex_);
        if (!initialized_) {
            loadConfig(configPath);
            initialized_ = true;
        }
    }

    std::string getValue(const std::string& key) const {
        if (!initialized_) {
            throw std::runtime_error("Config not initialized");
        }
        auto it = config_.find(key);
        return it != config_.end() ? it->second : "";
    }

private:
    FixedConfig() = default;

    void loadConfig(const std::string& path) {
        // Load configuration from file
    }

    std::map<std::string, std::string> config_;
    std::mutex initMutex_;
    bool initialized_ = false;
};

// Fixed: Logger with no circular dependency
class FixedLogger {
public:
    static FixedLogger& getInstance() {
        static FixedLogger instance;
        return instance;
    }

    void log(const std::string& msg) {
        // Fixed: No dependency on config during logging
        std::cout << msg << std::endl;
    }

private:
    FixedLogger() = default;
};

// Fixed: Controlled initialization order in main
int main() {
    // Explicit initialization order
    FixedConfig::getInstance().initialize("/etc/app/config.yaml");
    FixedLogger::getInstance().log("Application starting");
    return 0;
}

CVE Examples

This CWE is marked as PROHIBITED for direct CVE mapping as it represents a code quality/design concern rather than a direct security vulnerability.


  • CWE-710: Improper Adherence to Coding Standards (parent)
  • CWE-543: Use of Singleton Pattern Without Synchronization (related)
  • CWE-1058: Invokable Control Element in Multi-Thread Context with non-Final Static (related)

References

  1. MITRE Corporation. "CWE-1063: Creation of Class Instance within a Static Code Block." https://cwe.mitre.org/data/definitions/1063.html
  2. Bloch, Joshua. "Effective Java, Third Edition." Item 83: Use lazy initialization judiciously.
  3. Oracle. "Java Language Specification - Initialization."