9.3 KiB
9.3 KiB
🔒 FAST API HARDENING - IMPLEMENTASI
✅ Status: HARDENING COMPLETED
🎯 FITUR HARDENING YANG DIIMPLEMENTASI
1. Rate Limiting ✅
Implementasi:
- ✅ File-based rate limiting (bisa upgrade ke Redis nanti)
- ✅ Default: 100 requests per minute per API key
- ✅ Configurable per API key via database
- ✅ Response headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset - ✅ Return 429 Too Many Requests jika limit exceeded
Location:
src/Helpers/RateLimitHelper.php-checkRateLimit()src/Middleware/ApiKeyMiddleware.php- Rate limit check
Configuration:
-- Set custom rate limit per API key
UPDATE api_keys
SET rate_limit_per_minute = 200,
rate_limit_window = 60
WHERE id = 1;
Response Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705123456
Retry-After: 45
2. IP Whitelist ✅
Implementasi:
- ✅ IP whitelist per API key (optional)
- ✅ Support single IP atau CIDR notation (e.g.,
192.168.1.0/24) - ✅ Support comma-separated atau JSON array
- ✅ Default: disabled (allow all IPs)
- ✅ Return 403 Forbidden jika IP tidak di whitelist
Location:
src/Helpers/RateLimitHelper.php-checkIpWhitelist()src/Middleware/ApiKeyMiddleware.php- IP whitelist check
Configuration:
-- Enable IP whitelist untuk API key
UPDATE api_keys
SET enable_ip_whitelist = 1,
ip_whitelist = '192.168.1.100,10.0.0.0/24,203.0.113.0/24'
WHERE id = 1;
-- Atau menggunakan JSON array
UPDATE api_keys
SET enable_ip_whitelist = 1,
ip_whitelist = '["192.168.1.100", "10.0.0.0/24"]'
WHERE id = 1;
Format IP Whitelist:
- Single IP:
192.168.1.100 - CIDR:
192.168.1.0/24 - Comma-separated:
192.168.1.100,10.0.0.0/24 - JSON array:
["192.168.1.100", "10.0.0.0/24"]
3. API Key Expiration ✅
Implementasi:
- ✅ Expiration date per API key (optional)
- ✅ Check expiration saat validation
- ✅ Return 401 Unauthorized jika expired
- ✅ Default: never expires (NULL)
Location:
src/Helpers/RateLimitHelper.php-checkExpiration()src/Middleware/ApiKeyMiddleware.php- Expiration check
Configuration:
-- Set expiration date untuk API key
UPDATE api_keys
SET expires_at = '2025-12-31 23:59:59'
WHERE id = 1;
-- Remove expiration (never expires)
UPDATE api_keys
SET expires_at = NULL
WHERE id = 1;
4. Request Timestamp Validation ✅
Implementasi:
- ✅ Optional timestamp validation untuk prevent replay attack
- ✅ Default: disabled (log only, tidak block)
- ✅ Max age: 5 minutes (300 seconds)
- ✅ Header:
X-Timestampatau bodytimestamp
Location:
src/Helpers/RateLimitHelper.php-validateTimestamp()src/Middleware/ApiKeyMiddleware.php- Timestamp validation
Usage:
POST /fast/check_bill
X-Client-ID: your_client_id
X-Client-Secret: your_client_secret
X-Timestamp: 1705123456
Enable Blocking:
Uncomment line di ApiKeyMiddleware.php:
// Uncomment untuk block request dengan timestamp invalid
return ResponseHelper::json($handler->handle($request)->withStatus(400),
['status' => 'error', 'message' => $timestampValidation['message']], 400);
📊 DATABASE SCHEMA
New Columns di api_keys Table:
ALTER TABLE api_keys
ADD COLUMN rate_limit_per_minute INT DEFAULT 100,
ADD COLUMN rate_limit_window INT DEFAULT 60,
ADD COLUMN enable_ip_whitelist TINYINT(1) DEFAULT 0,
ADD COLUMN ip_whitelist TEXT NULL,
ADD COLUMN expires_at DATETIME NULL,
ADD COLUMN last_used_at DATETIME NULL,
ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
-- Indexes
CREATE INDEX idx_api_keys_expires_at ON api_keys(expires_at);
CREATE INDEX idx_api_keys_is_active ON api_keys(is_active);
CREATE INDEX idx_api_keys_last_used_at ON api_keys(last_used_at);
Migration Script:
php run_hardening_migration.php
Note: Script akan otomatis skip jika column/index sudah ada.
🔧 IMPLEMENTATION DETAILS
1. Rate Limiting
Storage:
- File-based cache di
storage/cache/rate_limit/ - Format: JSON file per API key
- Auto cleanup saat window expired
Algorithm:
- Sliding window per API key
- Counter reset setiap window seconds
- Thread-safe dengan file locking
Upgrade Path:
- Bisa upgrade ke Redis/Memcached nanti
- Interface sudah abstract, cukup ganti storage layer
2. IP Whitelist
Validation:
- Check exact match untuk single IP
- Check CIDR range untuk subnet
- Support IPv4 (IPv6 bisa ditambahkan nanti)
Performance:
- Cached di memory per request
- No database query jika disabled
3. API Key Expiration
Validation:
- Check saat API key validation
- Compare dengan current timestamp
- Log expired attempts
4. Request Timestamp
Validation:
- Optional (tidak block by default)
- Max age: 5 minutes
- Prevent replay attack
🛡️ SECURITY FLOW
Request → ApiKeyMiddleware
↓
1. Extract X-Client-ID & X-Client-Secret
↓
2. Validate API Key (database)
↓
3. ✅ Check Expiration (if column exists)
↓
4. ✅ Check IP Whitelist (if enabled)
↓
5. ✅ Check Rate Limit (always enabled)
↓
6. ✅ Validate Timestamp (optional, log only)
↓
7. Attach API Key to Request
↓
8. Add Rate Limit Headers to Response
↓
Response
📝 USAGE EXAMPLES
Example 1: Basic API Call (No Hardening Config)
POST /fast/check_bill
X-Client-ID: ABC_1234567890_abcdef
X-Client-Secret: 64_char_hex_string
Response:
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1705123456
Example 2: Rate Limit Exceeded
POST /fast/check_bill
X-Client-ID: ABC_1234567890_abcdef
X-Client-Secret: 64_char_hex_string
Response:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705123456
Retry-After: 45
{
"status": "error",
"message": "Rate limit exceeded. Please try again later.",
"retry_after": 45
}
Example 3: IP Not Whitelisted
POST /fast/check_bill
X-Client-ID: ABC_1234567890_abcdef
X-Client-Secret: 64_char_hex_string
IP: 192.168.1.200 (not in whitelist)
Response:
HTTP/1.1 403 Forbidden
{
"status": "error",
"message": "IP address not allowed"
}
Example 4: API Key Expired
POST /fast/check_bill
X-Client-ID: ABC_1234567890_abcdef
X-Client-Secret: 64_char_hex_string
Response:
HTTP/1.1 401 Unauthorized
{
"status": "error",
"message": "API key has expired"
}
⚙️ CONFIGURATION
Environment Variables (Optional):
# Rate Limiting (defaults)
RATE_LIMIT_DEFAULT=100
RATE_LIMIT_WINDOW=60
# Timestamp Validation (defaults)
TIMESTAMP_MAX_AGE=300
Database Configuration:
-- Set custom rate limit
UPDATE api_keys
SET rate_limit_per_minute = 200,
rate_limit_window = 60
WHERE id = 1;
-- Enable IP whitelist
UPDATE api_keys
SET enable_ip_whitelist = 1,
ip_whitelist = '192.168.1.100,10.0.0.0/24'
WHERE id = 1;
-- Set expiration
UPDATE api_keys
SET expires_at = '2025-12-31 23:59:59'
WHERE id = 1;
🔍 MONITORING & LOGGING
API Logs:
Semua hardening events di-log ke api_logs table:
-- View rate limit events
SELECT * FROM api_logs
WHERE status = 'rate_limited'
ORDER BY created_at DESC;
-- View IP blocked events
SELECT * FROM api_logs
WHERE status = 'ip_blocked'
ORDER BY created_at DESC;
-- View expired API keys
SELECT * FROM api_logs
WHERE status = 'expired'
ORDER BY created_at DESC;
Rate Limit Cache Files:
# View rate limit cache
ls -la storage/cache/rate_limit/
# Clear rate limit cache (emergency)
rm -rf storage/cache/rate_limit/*
✅ BACKWARD COMPATIBILITY
Semua hardening features adalah backward compatible:
- ✅ Rate Limiting - Always enabled, default 100 req/min
- ✅ IP Whitelist - Default disabled (allow all IPs)
- ✅ Expiration - Default never expires (NULL)
- ✅ Timestamp - Optional, tidak block by default
Jika column belum ada di database:
- Hardening features akan skip gracefully
- Error di-log tapi request tetap di-allow (fail open)
- Tidak ada breaking changes untuk existing API keys
🚀 UPGRADE PATH
Future Enhancements:
-
Redis/Memcached untuk Rate Limiting
- Ganti file-based cache dengan Redis
- Better performance untuk high traffic
-
Advanced Rate Limiting
- Per-endpoint rate limiting
- Burst protection
- Adaptive rate limiting
-
Request Signature (HMAC)
- HMAC SHA256 signature validation
- Prevent request tampering
- Replay attack protection
-
API Key Rotation
- Automatic key rotation
- Grace period untuk old keys
- Notification sebelum expiration
📋 CHECKLIST
- ✅ Rate Limiting implemented
- ✅ IP Whitelist implemented
- ✅ API Key Expiration implemented
- ✅ Request Timestamp validation implemented
- ✅ Database migration script created
- ✅ Backward compatible (fail open)
- ✅ Error handling & logging
- ✅ Response headers added
- ✅ Documentation created
Status: ✅ HARDENING COMPLETED
Level Security: ENHANCED (dari basic ke hardened)
Production Ready: ✅ YES (backward compatible)