Rate Limiting 與暴力破解
攻擊手法
攻擊者使用大量 IP 或慢速攻擊繞過 Rate Limit:
# 攻擊者腳本:使用代理 IP 繞過 IP-based Rate Limit
import requests
proxies = ["192.168.1.1:8080", "10.0.0.1:3128", ...]
passwords = ["123456", "password", "admin123", ...]
for i, pwd in enumerate(passwords):
proxy = proxies[i % len(proxies)]
r = requests.post("https://target.com/login",
json={"username": "admin", "password": pwd},
proxies={"http": f"http://{proxy}"}
)
if r.status_code == 200:
print(f"密碼找到了: {pwd}")
break
防護策略
| 方法 | 說明 | 繞過難度 | |------|------|---------| | IP-based | 限制每 IP 每分鐘請求數 | 低(代理 IP) | | User-based | 限制每帳號每分鐘請求數 | 中 | | Behavioral | 分析請求模式(速度、順序) | 高 | | CAPTCHA | 超過閾值後啟用驗證碼 | 高 |
Vibe Prompt
「幫我在 FastAPI 中實作多層 Rate Limiting:IP-based + User-based + 異常檢測。」
from collections import defaultdict
import time
class RateLimiter:
def __init__(self):
self.ip_requests = defaultdict(list)
self.user_requests = defaultdict(list)
def check(self, ip: str, user_id: str = None):
now = time.time()
# IP-based: 每分鐘 60 次
ip_reqs = [t for t in self.ip_requests[ip] if now - t < 60]
if len(ip_reqs) >= 60:
return False, "IP 請求過多"
if user_id:
user_reqs = [t for t in self.user_requests[user_id] if now - t < 60]
if len(user_reqs) >= 30:
return False, "用戶請求過多"
self.user_requests[user_id].append(now)
self.ip_requests[ip].append(now)
return True, "ok"
關鍵要點
- ✅ Rate Limiting 防止:暴力破解、DDoS、資源耗盡
- ✅ 三種策略:固定視窗、滑動視窗、Token Bucket(建議用滑動視窗)
- ✅ 回應 Headers:
X-RateLimit-Limit、X-RateLimit-Remaining、Retry-After - ✅ 分層限流:API Gateway → Application → Database 各層級都要有
各種策略比較
| 策略 | 實作 | 精確度 | 記憶體 | |------|------|:-----:|:-----:| | 固定視窗 | 每分鐘重置計數器 | 低(邊界突波) | 低 | | 滑動視窗 | 記錄時間戳串列 | 高 | 中 | | 滑動視窗計數 | 前一個視窗 + 當前視窗比例 | 高 | 低 | | Token Bucket | 固定速率補充 Token | 中 | 低 |
程式碼範例
from fastapi import FastAPI, HTTPException
from collections import defaultdict
import time
app = FastAPI()
rate_limits = defaultdict(list) # {ip: [timestamp1, timestamp2, ...]}
@app.middleware("http")
async def rate_limit_middleware(request, call_next):
ip = request.client.host
now = time.time()
window = 60 # 60 秒視窗
max_requests = 100
# 清除過期紀錄
rate_limits[ip] = [t for t in rate_limits[ip] if now - t < window]
if len(rate_limits[ip]) >= max_requests:
raise HTTPException(429, "Too Many Requests")
rate_limits[ip].append(now)
return await call_next(request)
常見錯誤
程式碼範例
Rate Limiting:防止 API 被濫用
Rate Limiting(頻率限制)是 API 安全的第一道防線。沒有 Rate Limiting,攻擊者可以:
- 每秒嘗試 1000 組密碼暴力破解登入
- 用 for 迴圈建立 10000 個假帳號
- 無限次呼叫付費 API 導致你破產
Rate Limiting 的實作方式
| 方式 | 原理 | 實作難度 | |:----|:----|:--------| | IP Based | 同一 IP 每分鐘 N 次 | 低(但 VPN 可繞過) | | Token Based | 同一 API Key 每分鐘 N 次 | 中(需認證系統) | | User Based | 同一使用者每分鐘 N 次 | 中(需使用者識別) | | Global | 所有請求總和 N/sec | 低(基本保護) |
滲透測試如何繞過 Rate Limit?
| 技術 | 說明 | |:----|:----| | IP 輪換 | 使用代理 IP Pool | | 分散時間 | 拉長攻擊時間,不觸發閾值 | | 非同步攻擊 | 同時從多個 IP 發送 |
下一章預告:滲透測試報告
學完所有攻擊技術後,最後一章教你如何撰寫專業的滲透測試報告。