WAF和註射保護
1)為什麼WAF在API時代
即使經過嚴格的驗證和參數化,註射也是由於以下原因引起的:- 集成的「長尾巴」(遺傳代碼,附屬網絡手冊),
- 解析差異(代理↔框架),
- 新的協議/混淆旁路技術。
- WAF在代碼發布之前給出了早期故障(早期破壞)和「虛擬補丁」的界限,但無法替代安全開發。
2)威脅模型: API的註射類型
SQLi/ORMi: classic/boolean/time-based/stacked;blind通過延遲。
NoSQLi (Mongo/Elastic):運算符'$ne/$gt'、JSON injection, regex-DoS。
Command Injection/RCE: shell-metasivols,變換參數,unsafe deserialization → code exec。
XXE: XML 中的外部實體/DTD。
SSRF: 訪問'169。254.169.254英寸/內部服務;DNS-rebinding.
Template Injection: Jinja/Thymeleaf/Handlebars; `{{77}}`.
LDAP/EL Injection, XPath, Header injection (CRLF), Path traversal.
GraphQL特定:「__計劃」引入,查詢深度/復雜性。
JSON/JS特定:原型Pollution(「__原型__」,「constructor」)。
gRPC/Protobuf:超頻消息,通過電路不匹配進行現場竊聽。
3) WAF架構
CDN-WAF周邊:快速geo/ASN過濾、基本機器人控制、緩存/反打孔。
L7外圍(NGINX/Envoy/APISIX/Kong):精確的解析、深層規則、與PDP/限制的集成。
Sidekar/Mashe (Envoy WASM/Filter):接近數據的per服務對內部API的假陽性較小。
建議:雙層模型(CDN-WAF+L7 WAF)。
4)分離,正常化和反旁路
WAF必須看到與應用程序相同的規範表示:- 路徑正常化('/a/% 2e% 2e/b' →故障),'UTF-8'/Unicode confusables, NUL字節。
- 統一解碼:URL -/HTML -/Unicode -/Base64層,禁止雙重解碼。
- 限制:「max_headers」,「max_header_size」,「max_body_size」,「max_args」,JSON深度,多片限制,2x gzip/zip炸彈禁令。
- Content-Type策略:「application/json」僅適用於JSON尾端;拒絕「polyglot」。
5)規則模型
負面(簽名):OWASP CRS(SQLi/XSS/SSRF/Java/Node RCE等)。快速啟動。
正面(allow-list):嚴格的方案(JSON Schema/Protobuf),類型和範圍;沿著路線。
異常/得分:「可疑」特征的總和→鎖定閾值。
上下文:「POST/payments」和「GET/status」的不同配置文件;小於FP。
6)保護單元(捆綁在一起)
1.方案和類型:JSON 方案/Protobuf驗證業務邏輯。
2.參數化:準備好的表達式,ORM賓語,禁止串聯。
3.輸出映射:HTML/JS/SQL上下文。
4.主體策略:Content-Type,尺寸,multipart限制,JSON手柄禁止二進制。
5.WAF規則:CRS+定制負面/正面。
6.Rate/Quota/Concurrency:brute/turtle DDoS抑制,公共形式的防護帽/挑戰。
7.網絡隔離:SSRF的egress策略(deny RFC1918/metadata/Unix sockets)。
8.頭部衛生:「X-Conte-Type-Options:nosniff」,前部的「Content-Security-Policy」,「Referrer-Policy」。
9.GraphQL guard:深度/復雜性限制,禁止在銷售(或角色門)中引入。
7)配置示例
7.1 NGINX + ModSecurity (OWASP CRS)
nginx load_module modules/ngx_http_modsecurity_module. so;
modsecurity on;
modsecurity_rules_file /etc/modsecurity/modsecurity. conf;
modsecurity_rules '
SecRuleEngine On
Connect CRS
Include /etc/modsecurity/crs/crs-setup. conf
Include /etc/modsecurity/crs/rules/.conf
Positive rules: JSON only and size limit
SecRule REQUEST_HEADERS:Content-Type "!@rx ^application/json($;)" "id:10001,phase:1,deny,status:415,msg:'Only JSON allowed'"
SecRequestBodyLimit 1048576
SecRequestBodyNoFilesLimit 1048576
Local Address Block (SSRF)
SecRule REQUEST_HEADERS:Host "@ipmatch 127. 0. 0. 0/8 10. 0. 0. 0/8 169. 254. 0. 0/16 192. 168. 0. 0/16" \
"id:10002,phase:1,deny,status:403,msg:'Blocked private range'"
';
server {
listen 443 ssl http2;
server_name api. example. com;
client_max_body_size 1m;
proxy_request_buffering on; # защита от slow-POST proxy_read_timeout 300ms;
proxy_connect_timeout 100ms;
location /v1/ {
proxy_pass http://app_backends;
}
}
7.2 Envoy HTTP WAF (WASM + JSON Schema + SSRF egress-deny)
yaml http_filters:
- name: envoy. filters. http. wasm typed_config:
config:
vm_config: { vm_id: waf, code: { local: { filename: /plugins/waf. wasm } } }
configuration:
"@type": type. googleapis. com/google. protobuf. Struct value:
crs_profile: "strict"
deny_patterns: ["(?i)union. select", "(?i)(sleep benchmark)\\s\\("]
json_schema:
"/v1/payments:create": "/schemas/payments_create. json"
- name: envoy. filters. http. router
Egress SSRF guard (L4): deny private ranges from gateway filter_chains:
- filters:
- name: envoy. filters. network. tcp_proxy typed_config:
stat_prefix: egress cluster: internet access_log: [...]
tunneling_config:
hostname: "%REQ(:authority)%"
transport_socket:
name: envoy. transport_sockets. tls
7.3 APISIX:類型限制和反混淆
yaml routes:
- uri: /v1/
plugins:
cors: { allow_origins: "https://app. example. com" }
request-validation:
body_schema:
{"type":"object","properties":{"amount":{"type":"number","minimum":1}},"required":["amount"]}
uri-blocker:
block_rules: ["..","%2e%2e","%2f..","\\x00"] # traversal/NULL proxy-rewrite:
headers:
set:
X-Content-Type-Options: "nosniff"
8)調節和減少誤報(FP)
按路線配置文件:僅在適當時才有嚴格的規則(例如"/search"允許"/"%")。
Shadow/Report-Only:在單元前計算觸發;A/B比較指標。
「嘈雜」合法參數的定制allow列表。
評分:僅在指標和>閾值時阻止。
實驗:→自動回滾的新規則的流量百分比很小。
9)可觀察性和力學
Метрики: `waf_block_total{rule}`, `waf_anomaly_score`, `request_body_rejected_total`, `schema_violation_total`, `ssrf_block_total`.
Logi(采樣):規則,查詢的一部分(編輯),「trace_id」, 「tenant」, 「route」,原因。偽裝PII/秘密。
Dashbords:頂級規則/路徑,FP集群,發布後的揚聲器。
事件:保存工件(payload、pcap如有必要)、RCA產品和「虛擬補丁」。
10)測試和混亂場景
WAF繞行語料庫(SQLi/XSS/SSRF),雙/三重編碼,由Unicode混合。
Parsing差異:發送代理和框架可能發散的payload(參數對比、數組、'vs'&)。
Slow-POST/oversize,zip炸彈,多件形式,有缺陷的邊界。
GraphQL:深度/復雜度發生器,限制和計時器檢查。
11)反模式
「打開CRS並忘記了」:沒有電路,沒有路線調整。
帶有原始查詢體和PII的日誌。
沒有標準化/尺寸限制→繞行,每個解析的DoS。
跳過「Content-Type」/charset檢查→多重攻擊。
雲元數據的SSRF →缺少無表征濾波器。
一個用於外部和內部API的通用配置文件。
「夥伴」的失控例外→外圍漏洞。
12) iGaming/財務細節
加固的支付/輸出手柄上的配置文件:小型車身限制、嚴格的方案、帳戶/IBAN/PAN字段的deny列表(掩蔽、格式檢查)。
PSP/KYC的Webhooks:HMAC簽名/互連TLS,單獨的WAF配置文件,反復制。
地理/ASN過濾器和行為限制,以防止機器人註冊和獎勵算法。
事件日誌不變(審計),按司法管轄區存儲。
13)準備就緒支票清單
- 雙層WAF (CDN+L7)、單一規範化和尺寸限制。
- OWASP CRS包括在內,按路線定制規則;寫筆上的JSON 計劃/Protobuf。
- Content-Type/charset策略;禁止雙重解碼/NULL/traversal。
- SSRF-egress 單元到私有範圍/metadata;DNS重組保護。
- Rate/Quota/Concurrency和Anti-Bot(挑戰)在公共表格上。
[] Shadow/Report-Only → canary → enforce;SLO和FP上的自動回滾。
- 蒙版度量/logi/traces;「頂級規則」/FP dashbords。
- 虛擬補丁和RCA的花花公子;定期的繞行測試。
- PSP/KYC網絡手冊、支付筆和內部API的單獨配置文件。
14) TL;DR
按層構建保護:歸一化和限制→方案/類型→參數化→ WAF (CRS+cast) → rate/bot過濾器→ egress SSRF單元。在陰影→金絲雀中按路線調節,運行新規則,關註度量/FP,並在代碼虛假化之前進行「虛擬補丁」。對於支付/webhook路徑-單獨嚴格的配置文件,HMAC/mTLS和最低限度的信任窗口。