Empty Code Block

Description

Empty Code Block occurs when source code contains a block that does not contain any code - the block is empty. This includes empty function bodies, empty conditional branches (if/else), empty loops, empty exception handlers, and empty synchronized blocks. Empty blocks typically indicate incomplete implementation, accidentally deleted code, or residual code from refactoring. While sometimes intentional, empty blocks are a code smell that often indicates a bug or missing functionality.

Risk

Empty code blocks have various security implications depending on context. Empty exception handlers (catch blocks) silently swallow errors, potentially hiding security failures. Empty synchronized blocks provide no thread safety despite suggesting protection. Empty conditional branches may indicate missing security checks. Empty function bodies may leave security callbacks unimplemented. Empty loops can cause infinite hangs if the exit condition is never met. The deceptive appearance of functional code misleads code reviewers into thinking security controls exist when they don't.

Solution

Review all empty code blocks for intent. If intentional, add a comment explaining why the block is empty. If unintentional, implement the missing functionality. Use static analysis tools to detect empty blocks. For exception handlers, at minimum log the exception. For synchronized blocks, remove if unnecessary or implement proper synchronization. Consider using TODO comments or assertions to mark incomplete implementations. Establish coding standards that require justification for empty blocks.

Common Consequences

ImpactDetails
OtherScope: Other

Reduce Reliability - Empty blocks may indicate missing functionality that affects system behavior.
OtherScope: Other

Varies by Context - Impact depends on what the empty block should have contained.
IntegrityScope: Integrity

Unexpected State - Empty handlers may leave the system in invalid states after errors.

Example Code

Vulnerable Code

// Vulnerable: Various empty code blocks
public class VulnerableProcessor {

    // Vulnerable: Empty method body
    public void validateInput(String input) {
        // Missing validation implementation!
    }

    // Vulnerable: Empty exception handler
    public void processData(String data) {
        try {
            riskyOperation(data);
        } catch (Exception e) {
            // Empty catch - exception silently ignored!
        }
    }

    // Vulnerable: Empty synchronized block
    private int counter = 0;

    public void incrementCounter() {
        synchronized (this) {
            // Empty sync block provides no protection!
        }
        counter++;  // This is still unprotected!
    }

    // Vulnerable: Empty if/else branches
    public void handleRequest(Request request) {
        if (request.isAuthenticated()) {
            // Supposed to process authenticated requests
        } else {
            // Supposed to handle unauthenticated - does nothing!
        }
    }

    // Vulnerable: Empty loop body
    public void waitForCondition() {
        while (!condition) {
            // Empty loop - potential CPU spin/infinite loop
        }
    }

    // Vulnerable: Empty finally block
    public void cleanupResources() {
        try {
            allocateResource();
        } finally {
            // Cleanup code missing!
        }
    }
}
# Vulnerable: Empty code blocks in Python
class VulnerableService:

    def validate_credentials(self, username, password):
        """Should validate user credentials"""
        pass  # Empty implementation!

    def process_payment(self, amount):
        try:
            charge_card(amount)
        except PaymentError:
            pass  # Payment failures silently ignored!
        except Exception:
            pass  # All errors ignored!

    def handle_security_event(self, event):
        if event.severity == 'CRITICAL':
            pass  # Critical events ignored!
        elif event.severity == 'HIGH':
            pass  # High severity ignored!
        else:
            pass  # Everything ignored!

    def acquire_lock(self):
        with self._lock:
            pass  # Empty context manager - no protected code!
        self._shared_data += 1  # Unprotected!
// Vulnerable: Empty code blocks in C#
public class VulnerableHandler
{
    // Vulnerable: Empty method
    public virtual void OnSecurityEvent(SecurityEvent evt)
    {
        // Subclass might forget to override - event lost!
    }

    // Vulnerable: Empty catch
    public void SaveData(object data)
    {
        try
        {
            _database.Save(data);
        }
        catch (SqlException)
        {
            // Database errors silently ignored!
        }
    }

    // Vulnerable: Empty lock block
    private readonly object _lockObj = new object();
    private int _value;

    public void UpdateValue(int newValue)
    {
        lock (_lockObj)
        {
            // Empty lock - provides no protection!
        }
        _value = newValue;  // Still unprotected!
    }

    // Vulnerable: Empty conditional
    public void ProcessInput(string input)
    {
        if (IsMalicious(input))
        {
            // Should block malicious input - does nothing!
        }
        // Continues to process potentially malicious input
        ExecuteCommand(input);
    }
}
// Vulnerable: Empty code blocks in JavaScript
class VulnerableAPI {

    // Vulnerable: Empty function
    validateToken(token) {
        // Missing implementation - all tokens pass!
    }

    // Vulnerable: Empty catch
    async fetchUserData(userId) {
        try {
            return await this.db.query(`SELECT * FROM users WHERE id = ${userId}`);
        } catch (error) {
            // Database errors silently ignored
        }
    }

    // Vulnerable: Empty if block
    handlePermissions(user, action) {
        if (!user.hasPermission(action)) {
            // Should deny access - does nothing!
        }
        // Continues regardless of permissions
        this.performAction(action);
    }

    // Vulnerable: Empty callback
    secureOperation(callback) {
        this.checkSecurity(() => {
            // Empty callback - security check result ignored
        });
        this.doOperation();  // Proceeds anyway
    }
}

Fixed Code

// Fixed: Proper implementation of code blocks
public class FixedProcessor {

    private static final Logger logger = LoggerFactory.getLogger(FixedProcessor.class);

    // Fixed: Implemented validation
    public void validateInput(String input) throws ValidationException {
        if (input == null || input.trim().isEmpty()) {
            throw new ValidationException("Input cannot be null or empty");
        }
        if (input.contains("<script>")) {
            throw new ValidationException("Potential XSS detected");
        }
        // Additional validation...
    }

    // Fixed: Proper exception handling
    public void processData(String data) throws ProcessingException {
        try {
            riskyOperation(data);
        } catch (IOException e) {
            logger.error("IO error processing data", e);
            throw new ProcessingException("Failed to process data", e);
        } catch (Exception e) {
            logger.error("Unexpected error processing data", e);
            throw new ProcessingException("Processing failed", e);
        }
    }

    // Fixed: Synchronized block contains protected code
    private int counter = 0;

    public void incrementCounter() {
        synchronized (this) {
            counter++;  // Protected by synchronization
        }
    }

    // Fixed: Implemented conditional branches
    public void handleRequest(Request request) throws SecurityException {
        if (request.isAuthenticated()) {
            processAuthenticatedRequest(request);
        } else {
            logger.warn("Unauthenticated request attempt from {}",
                request.getRemoteAddr());
            throw new SecurityException("Authentication required");
        }
    }

    // Fixed: Loop has proper body
    public void waitForCondition() throws TimeoutException {
        long startTime = System.currentTimeMillis();
        long timeout = 30000;

        while (!condition) {
            // Fixed: Proper waiting with timeout
            if (System.currentTimeMillis() - startTime > timeout) {
                throw new TimeoutException("Condition not met within timeout");
            }
            try {
                Thread.sleep(100);  // Avoid CPU spin
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new TimeoutException("Wait interrupted");
            }
        }
    }

    // Fixed: Finally block performs cleanup
    private Resource resource;

    public void cleanupResources() {
        try {
            resource = allocateResource();
            useResource(resource);
        } finally {
            if (resource != null) {
                try {
                    resource.close();
                } catch (Exception e) {
                    logger.warn("Error closing resource", e);
                }
            }
        }
    }

    // Fixed: Intentionally empty block with documentation
    @SuppressWarnings("EmptyBlock")
    public void optionalCallback(Event event) {
        if (event.getType() == EventType.DEBUG) {
            // Intentionally ignored in production - debug events are for development only
            // See ticket PROJ-1234 for rationale
        } else {
            processEvent(event);
        }
    }
}
# Fixed: Proper implementation in Python
import logging

logger = logging.getLogger(__name__)


class FixedService:

    def validate_credentials(self, username: str, password: str) -> bool:
        """Validate user credentials against stored hash."""
        if not username or not password:
            logger.warning("Empty credentials provided")
            return False

        user = self._get_user(username)
        if not user:
            logger.warning(f"User not found: {username}")
            return False

        return self._verify_password(password, user.password_hash)

    def process_payment(self, amount: float) -> PaymentResult:
        """Process payment with proper error handling."""
        try:
            result = charge_card(amount)
            logger.info(f"Payment processed: {amount}")
            return result

        except PaymentError as e:
            logger.error(f"Payment failed: {e}")
            raise PaymentProcessingError(f"Payment of {amount} failed") from e

        except Exception as e:
            logger.exception("Unexpected payment error")
            raise PaymentProcessingError("Payment processing unavailable") from e

    def handle_security_event(self, event: SecurityEvent) -> None:
        """Handle security events based on severity."""
        if event.severity == 'CRITICAL':
            logger.critical(f"CRITICAL security event: {event}")
            self._alert_security_team(event)
            self._trigger_incident_response(event)

        elif event.severity == 'HIGH':
            logger.error(f"High severity security event: {event}")
            self._alert_security_team(event)

        else:
            logger.warning(f"Security event: {event}")
            self._log_security_event(event)

    def acquire_lock(self) -> None:
        """Thread-safe update with proper locking."""
        with self._lock:
            # Fixed: Protected code inside the context manager
            self._shared_data += 1
            self._last_updated = datetime.now()


# Fixed: Abstract method for required implementation
from abc import ABC, abstractmethod


class SecurityHandler(ABC):
    @abstractmethod
    def on_security_event(self, event: SecurityEvent) -> None:
        """Subclasses MUST implement this method."""
        pass  # This 'pass' is fine - it's abstract
// Fixed: Proper implementation in C#
public class FixedHandler
{
    private readonly ILogger<FixedHandler> _logger;

    // Fixed: Abstract method forces implementation
    public abstract void OnSecurityEvent(SecurityEvent evt);

    // Or: Implemented virtual method with default behavior
    public virtual void OnSecurityEventWithDefault(SecurityEvent evt)
    {
        _logger.LogWarning("Security event received: {Event}", evt);
        // Default handling that subclasses can extend
    }

    // Fixed: Proper exception handling
    public void SaveData(object data)
    {
        try
        {
            _database.Save(data);
            _logger.LogInformation("Data saved successfully");
        }
        catch (SqlException ex)
        {
            _logger.LogError(ex, "Database error saving data");
            throw new DataPersistenceException("Failed to save data", ex);
        }
    }

    // Fixed: Lock block contains protected code
    private readonly object _lockObj = new object();
    private int _value;

    public void UpdateValue(int newValue)
    {
        lock (_lockObj)
        {
            // Fixed: Protected code inside lock
            _value = newValue;
            _lastUpdated = DateTime.UtcNow;
        }
    }

    // Fixed: Conditional blocks implemented
    public void ProcessInput(string input)
    {
        if (IsMalicious(input))
        {
            _logger.LogWarning("Malicious input blocked: {Input}", input);
            throw new SecurityException("Malicious input detected");
        }

        // Only reached for non-malicious input
        ExecuteCommand(input);
    }
}
// Fixed: Proper implementation in JavaScript
class FixedAPI {

    // Fixed: Implemented validation
    validateToken(token) {
        if (!token) {
            throw new AuthenticationError('Token required');
        }

        try {
            const decoded = jwt.verify(token, this.secret);
            return decoded;
        } catch (error) {
            this.logger.warn('Invalid token attempt', { error: error.message });
            throw new AuthenticationError('Invalid token');
        }
    }

    // Fixed: Proper error handling
    async fetchUserData(userId) {
        try {
            // Fixed: Parameterized query
            return await this.db.query(
                'SELECT * FROM users WHERE id = ?',
                [userId]
            );
        } catch (error) {
            this.logger.error('Database error fetching user', {
                userId,
                error: error.message
            });
            throw new DatabaseError('Failed to fetch user data');
        }
    }

    // Fixed: Permission check enforced
    handlePermissions(user, action) {
        if (!user.hasPermission(action)) {
            this.logger.warn('Permission denied', {
                userId: user.id,
                action
            });
            throw new ForbiddenError(`Permission denied for action: ${action}`);
        }

        // Only reached if permission granted
        this.performAction(action);
    }

    // Fixed: Callback result handled
    async secureOperation() {
        const securityResult = await this.checkSecurity();

        if (!securityResult.passed) {
            this.logger.error('Security check failed', securityResult);
            throw new SecurityError('Security check failed');
        }

        // Only proceed if security check passed
        return this.doOperation();
    }
}

CVE Examples

Empty code blocks, particularly empty catch blocks, have contributed to numerous vulnerabilities by silently ignoring security-relevant exceptions. However, specific CVEs typically map to the resulting weakness rather than this CWE directly.


  • CWE-1164: Irrelevant Code (parent)
  • CWE-1069: Empty Exception Block (child)
  • CWE-390: Detection of Error Condition Without Action (related)

References

  1. MITRE Corporation. "CWE-1071: Empty Code Block." https://cwe.mitre.org/data/definitions/1071.html
  2. SonarSource. "Code Smell: Empty Block."
  3. PMD. "Empty Statement Rules."