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
| Impact | Details |
|---|---|
| Other | Scope: Other Reduce Reliability - Empty blocks may indicate missing functionality that affects system behavior. |
| Other | Scope: Other Varies by Context - Impact depends on what the empty block should have contained. |
| Integrity | Scope: 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.
Related CWEs
- CWE-1164: Irrelevant Code (parent)
- CWE-1069: Empty Exception Block (child)
- CWE-390: Detection of Error Condition Without Action (related)
References
- MITRE Corporation. "CWE-1071: Empty Code Block." https://cwe.mitre.org/data/definitions/1071.html
- SonarSource. "Code Smell: Empty Block."
- PMD. "Empty Statement Rules."