📋 What Is It?
Unrestricted Resource Consumption occurs when APIs fail to limit computational resources, network bandwidth, or storage, allowing attackers to overwhelm the system through legitimate requests, leading to DoS, performance degradation, or excessive cloud costs.
API04
OWASP Rank
DoS
Primary Impact
$$$
Cloud Cost Explosion
⚠️ Common Exploits
- Rate Limit Abuse: Send 100,000 requests/minute to exhaust resources
- Large Payloads: Upload massive files or send huge JSON bodies
- Expensive Operations: Trigger complex queries or computations
- No Pagination: Request entire database in single query
- Batch Abuse: Request 10,000 items in batch operation
- Infinite Loops: Trigger recursive operations without limits
🔴 Attack Flow
1. Attacker discovers API endpoint
↓
2. No rate limiting or pagination detected
↓
3. Sends 50,000 requests in 1 minute
↓
4. Server CPU/memory exhausted
↓
5. BREACH: Service unavailable for all users!
↓
2. No rate limiting or pagination detected
↓
3. Sends 50,000 requests in 1 minute
↓
4. Server CPU/memory exhausted
↓
5. BREACH: Service unavailable for all users!
❌ Vulnerable Code
// Bad: No rate limiting!
@app.route('/api/users')
def get_users():
# Returns ALL users, no pagination!
users = User.query.all() ← Could be millions!
return jsonify(users)
// Bad: No file size limit
@app.route('/api/upload', methods=['POST'])
def upload_file():
file = request.files['file']
# No size check - attacker can upload 10GB file!
file.save(f'uploads/{file.filename}')
return {'status': 'uploaded'}
// Bad: Expensive operation without timeout
@app.route('/api/reports/generate')
def generate_report():
start_date = request.args.get('start')
end_date = request.args.get('end')
# No limit - could query 10 years of data!
data = Transaction.query.filter(
Transaction.date.between(start_date, end_date)
).all()
return generate_pdf(data) ← Memory exhaustion!
✅ Secure Code
// Good: Rate limiting + pagination
@limiter.limit("100 per minute")
@app.route('/api/users')
def get_users():
page = request.args.get('page', 1, type=int)
per_page = min(request.args.get('per_page', 20, type=int), 100)
# Paginated response
users = User.query.paginate(page=page, per_page=per_page)
return jsonify({
'users': users.items,
'total': users.total,
'page': page,
'pages': users.pages
})
// Good: File size limit
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
@app.route('/api/upload', methods=['POST'])
def upload_file():
file = request.files['file']
# Check file size
file.seek(0, os.SEEK_END)
size = file.tell()
file.seek(0)
if size > MAX_FILE_SIZE:
return {'error': 'File too large'}, 413
file.save(f'uploads/{secure_filename(file.filename)}')
return {'status': 'uploaded'}
// Good: Query limits + timeouts
@app.route('/api/reports/generate')
@timeout(30) # 30 second timeout
def generate_report():
start_date = parse_date(request.args.get('start'))
end_date = parse_date(request.args.get('end'))
# Limit date range to 90 days
if (end_date - start_date).days > 90:
return {'error': 'Max 90 days'}, 400
# Limit query results
data = Transaction.query.filter(
Transaction.date.between(start_date, end_date)
).limit(10000).all()
return generate_pdf_async(data) # Background job
✓ Prevention Checklist
- Implement rate limiting on all endpoints
- Add pagination to list endpoints (max 100 items)
- Set maximum request body size (e.g., 1MB)
- Limit file upload sizes
- Set query timeouts (e.g., 30 seconds)
- Limit batch operation sizes
- Implement request throttling per user/IP
- Set maximum page size in pagination
- Use async processing for expensive operations
- Monitor resource consumption metrics
- Implement circuit breakers
- Set connection pool limits
🔍 Detection & Tools
Testing Tools:
Apache JMeter
Locust
wrk
ab (Apache Bench)
Gatling
K6
Prevention Tools:
Flask-Limiter
Express Rate Limit
Spring Cloud Gateway
Kong
NGINX
Redis (rate limiting)
How to Test:
- Send thousands of rapid requests
- Test with large file uploads (1GB+)
- Request maximum pagination without limits
- Trigger expensive operations repeatedly
- Test batch endpoints with 10,000+ items
🌍 Real-World Breaches
- AWS Bill Shock: Attackers abuse APIs causing $10,000+ monthly bills
- GitHub (2018): 1.35 Tbps DDoS via memcached amplification attack
- E-commerce Sites: Cart APIs abused during sales, causing site crashes
- Cryptocurrency Exchanges: Trading APIs overwhelmed during high volatility
- SaaS Platforms: Free trial abuse leading to resource exhaustion
📌 Quick Tips
- DO NOT allow unlimited requests
- DO NOT return entire datasets
- DO NOT accept unlimited file sizes
- DO implement rate limiting everywhere
- DO paginate all list endpoints
- DO set timeouts on operations
- DO monitor resource usage
📜 Compliance
Related Standards:
- ISO 27001 A.12.1.3 - Capacity Management
- SOC 2 CC7.2 - Availability
- NIST 800-53 SC-5 - DoS Protection
- PCI-DSS Requirement 6.5.6
- CIS Controls 12.5