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"