Incorrect Behavior Order: Early Amplification
Description
Incorrect Behavior Order: Early Amplification is a vulnerability where a product allows an entity to perform a legitimate but expensive operation before authentication or authorization has been completed. This creates a denial-of-service vulnerability because attackers can trigger resource-intensive operations without proving their identity or having appropriate permissions. Common examples include loading files into memory before checking ownership, performing database queries before authentication, or executing cryptographic operations for unauthenticated requests.
Risk
Early amplification vulnerabilities enable denial-of-service attacks with minimal attacker effort. Unauthenticated users can exhaust server resources by repeatedly triggering expensive operations like file reads, database queries, or cryptographic computations. Since no authentication is required, attackers can make unlimited requests from spoofed or rotating IP addresses. The asymmetry between cheap attacker requests and expensive server operations creates an economic advantage for attackers. Systems may crash, become unresponsive, or deny service to legitimate users while processing malicious requests.
Solution
Always perform authentication and authorization checks before executing expensive operations. Structure code so that identity verification occurs at the earliest possible point in request processing. Implement rate limiting for pre-authentication endpoints. Use lazy loading patterns that defer resource-intensive operations until authorization is confirmed. Cache authentication results to avoid repeated expensive checks. Design APIs so that anonymous access is limited to lightweight operations only. Apply the principle of failing fast—reject unauthorized requests before committing resources.
Common Consequences
| Impact | Details |
|---|---|
| Availability | Scope: Availability DoS: Amplification - Attackers can trigger expensive operations without authentication. DoS: Crash, Exit, or Restart - System resources, CPU and memory, can be quickly consumed. This can lead to poor system performance or system crash. |
Example Code
Vulnerable Code
<?php
// Vulnerable: Loads entire file before checking authorization
function vulnerableDownloadFile($filename, $username) {
// Vulnerable: Expensive I/O operation BEFORE authorization
$file = file_get_contents($filename);
// Authorization check happens AFTER expensive operation
if ($file && isOwnerOf($username, $filename)) {
echo $file;
return true;
}
return false; // Resources already wasted
}
// Attacker can exhaust disk I/O and memory by requesting
// large files they don't own - the file is still loaded!
?>
# Vulnerable: Database query before authentication
def vulnerable_get_user_data(user_id, auth_token):
# Vulnerable: Expensive database query BEFORE auth check
user_data = database.query(
"SELECT * FROM users WHERE id = %s",
user_id
)
# Expensive joins and aggregations
orders = database.query(
"SELECT * FROM orders WHERE user_id = %s",
user_id
)
# Auth check happens AFTER database work
if not validate_token(auth_token, user_id):
return None # Database resources already consumed
return {"user": user_data, "orders": orders}
// Vulnerable: Cryptographic operation before authentication
public class VulnerableAuthService {
public boolean authenticate(String username, String password) {
// Vulnerable: Expensive key derivation BEFORE checking if user exists
byte[] hashedPassword = PBKDF2.hash(
password,
getSalt(username), // May not even exist
100000 // Expensive iterations
);
// Database lookup happens AFTER expensive crypto
User user = userRepository.findByUsername(username);
if (user == null) {
return false; // Crypto resources wasted
}
return Arrays.equals(hashedPassword, user.getPasswordHash());
}
}
// Vulnerable: Memory allocation before authentication
#include <stdlib.h>
int vulnerable_process_request(int client_fd) {
// Vulnerable: Allocates large buffer BEFORE authentication
char *buffer = malloc(10 * 1024 * 1024); // 10MB
if (!buffer) return -1;
// Read potentially large payload
ssize_t bytes = recv(client_fd, buffer, 10 * 1024 * 1024, 0);
// Authentication happens AFTER memory allocation and I/O
struct auth_header *auth = parse_auth_header(buffer);
if (!validate_auth(auth)) {
free(buffer);
return -1; // Memory already allocated and used
}
process_data(buffer, bytes);
free(buffer);
return 0;
}
Fixed Code
<?php
// Fixed: Check authorization BEFORE loading file
function secureDownloadFile($filename, $username) {
// Fixed: Authorization check FIRST
if (!isOwnerOf($username, $filename)) {
return false; // Fail fast, no resources used
}
// Expensive operation only after authorization confirmed
$file = file_get_contents($filename);
if ($file) {
echo $file;
return true;
}
return false;
}
// Alternative: Stream file instead of loading entirely
function secureStreamFile($filename, $username) {
// Fixed: Check authorization first
if (!isOwnerOf($username, $filename)) {
http_response_code(403);
return;
}
// Check file exists without loading
if (!file_exists($filename)) {
http_response_code(404);
return;
}
// Stream file to reduce memory usage
readfile($filename);
}
?>
# Fixed: Authenticate BEFORE expensive operations
def secure_get_user_data(user_id, auth_token):
# Fixed: Validate authentication FIRST
if not validate_token(auth_token, user_id):
raise AuthenticationError("Invalid token")
# Fixed: Check authorization before data access
if not is_authorized_for_user(auth_token, user_id):
raise AuthorizationError("Access denied")
# Expensive operations only after auth confirmed
user_data = database.query(
"SELECT * FROM users WHERE id = %s",
user_id
)
orders = database.query(
"SELECT * FROM orders WHERE user_id = %s",
user_id
)
return {"user": user_data, "orders": orders}
# Fixed: Rate limit unauthenticated endpoints
from functools import wraps
import time
def rate_limit(max_per_minute):
def decorator(f):
calls = {}
@wraps(f)
def wrapper(*args, **kwargs):
ip = get_client_ip()
now = time.time()
calls[ip] = [t for t in calls.get(ip, []) if now - t < 60]
if len(calls[ip]) >= max_per_minute:
raise RateLimitExceeded()
calls[ip].append(now)
return f(*args, **kwargs)
return wrapper
return decorator
// Fixed: Check user existence before expensive crypto
public class SecureAuthService {
public boolean authenticate(String username, String password) {
// Fixed: Lightweight check FIRST
User user = userRepository.findByUsername(username);
if (user == null) {
// Fixed: Fail fast without expensive crypto
// Add small delay to prevent user enumeration
simulateHashDelay();
return false;
}
// Fixed: Expensive operation only for valid users
byte[] hashedPassword = PBKDF2.hash(
password,
user.getSalt(),
100000
);
return MessageDigest.isEqual(hashedPassword, user.getPasswordHash());
}
private void simulateHashDelay() {
// Prevent timing attacks while avoiding expensive crypto
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// Fixed: Authenticate before allocating resources
#include <stdlib.h>
int secure_process_request(int client_fd) {
// Fixed: Read only the auth header first (small buffer)
char auth_buffer[256];
ssize_t auth_bytes = recv(client_fd, auth_buffer, sizeof(auth_buffer),
MSG_PEEK); // Peek without consuming
// Fixed: Validate authentication BEFORE large allocation
struct auth_header *auth = parse_auth_header(auth_buffer);
if (!validate_auth(auth)) {
return -1; // No resources allocated for invalid requests
}
// Fixed: Now allocate resources for authenticated request
size_t content_length = get_content_length(auth_buffer);
// Fixed: Validate content length before allocation
if (content_length > MAX_ALLOWED_SIZE) {
return -1;
}
char *buffer = malloc(content_length);
if (!buffer) return -1;
// Consume the peeked data and read the rest
ssize_t bytes = recv(client_fd, buffer, content_length, 0);
process_data(buffer, bytes);
free(buffer);
return 0;
}
CVE Examples
- CVE-2004-2458 — Tool creates directories before authenticating user, allowing unauthenticated directory creation.
References
- MITRE Corporation. "CWE-408: Incorrect Behavior Order: Early Amplification." https://cwe.mitre.org/data/definitions/408.html
- OWASP. "Denial of Service Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html