一、復雜的需求
WAF (WEB 應用防火墻) 用來保護 WEB 應用免受來自應用層的攻擊,作為防護物件的 WEB 應用,其功能和運行環境往往是復雜且千差萬別的,這導致即便防御某個特定的攻擊方式時,用戶需求也可能是細致而多樣的,
以最基本的 SQL 注入 (以下簡稱注入) 為例,注入攻擊當然是要防范的,但用戶可能還有以下需求:
- 某個域名或某些特定的 URL 不需要注入檢查
- 對來自外網的注入訪問進行攔截,來自內網的注入訪問只記錄不攔截
- 對特定的請求引數名或特定特征的請求引數不進行注入檢查
- 非作業時段不僅攔截還阻止該用戶一段時間訪問
- 對 admin 等管理賬號登錄后的訪問不進行注入檢查
- 對于只記錄不攔截的請求,附加一個特別的請求頭發往應用
- 對某些 URL 的注入訪問記錄下 HTTP 請求的全部報文
- 將 HTTP 回應碼為 500 的注入的日志緊急度設為 alert
- ...
以上需求,用戶可能只提出一項,也可能提出多項,還可能是不同的邏輯組合或更多的條件和動作,這還僅僅是防注入這項基本功能,如果有更多的應用防護需求,比如:
一個已登錄的非內網用戶在 10 秒鐘連續訪問 POST 方法的頁面 (非 AJAX 資料) 達到 5 次,則在 10 秒內延遲這個用戶的回應時間 0.5 秒;如果在未來 10 秒內繼續訪問 POST 方法頁面 3 次,則強制用戶登出并阻止登錄 30 秒;如果一個用戶 1 天內這種情形發生 5 次,則產生一條嚴重級別的告警,
我們該如何描述滿足這些需求的功能呢?
WAF是否能夠設計得足夠靈活,使得實施人員通過現場配置就能實作這個需求?
二、規則的局限性
大部分應用防火墻的配置以規則為核心,
傳統意義上的規則,其實質形式是獨立的一行行文本,每行文本有固定的結構/欄位,可以獨立地描述出一個功能,對用戶而言,書寫規則就是設定其中的引數和選項,這種規則的好處是簡單明了,用戶甚至可以在圖形化界面中完成規則的配置,但其弱點是不足以描述復雜的情形,

以防注入功能為例,如果它只有一個開啟或關閉的開關選項,或只能簡單地以區分站點來使用不同策略,顯然不能滿足前述的復雜需求,而企圖打造一個預先設定又包羅萬象的規則,則完全超出了“規則”的范疇,是不可能完成的任務,
追溯一下,用規則來描述防護功能始自于網路防火墻,網路防火墻的檢查物件是 TCP / IP 協議諸元,三/四層網路協議相對來說是簡單清晰的,用五元組就可以概括它們,以五元組為物件寫一些規則就能夠很好地實作防護,

但是,WEB 應用是怎么寫成的?WEB 應用是用 Java / PHP / Python 等編程語言寫成的,就像不可能用“規則"來書寫 WEB 應用一樣,試圖良好地對應用進行防護,也不可能通過傳統的“規則"來實作——無論寫多少條規則,
三、大家一起來編程?
既然應用是編程的,那么應用防火墻的配置可否也用編程的方式來實作?
以下是一個通用語言實作的例子,它的主功能是對請求引數進行注入檢查,檢查時會排除指定名字的引數,而且對不同來源訪問者 (外網或內網) 產生不同的日志和動作:
for arg in ARGS:
if arg['name'] in ['__utm', '__token']:
return PASS
if detect_sqli(remove_comment(url_decode(arg['value']))):
if is_private_address(REMOTE_ADDRESS):
log('SQLi and PASS')
return PASS
else:
log('SQLi and BLOCK')
return BLOCK
return PASS
功能是實作了,但看上去有點復雜,讓非程式員去寫這樣一段代碼難免強人所難 (比如對集合型別資料的遍歷獲取),而且完全不可能做到可視化,更重要的是,這僅是代碼片段 (其實就是函式),真的要整合起來使用,還面臨很多編程方面的問題,如:
- 除錯和容錯:
各種語法錯誤和鏈接錯誤,比如使用了不存在的變數或方法, - 批量控制:
怎樣實作全域和批量的改變,比如想讓 WAF 全域進入只記錄模式, - 作用域:
每個代碼片段有自己的作用域,如果想影響其他代碼片段應該怎么做?如何定義變數作用域? - 與預置防護集的關系:
WAF 必然自帶預置的防護集,用戶書寫的代碼與預置防護集的關系, - 引數的設定:
應用相關的可配置引數怎么處理,是作為常量寫在程式里 (難以維護) 還是另作一個組態檔 (程式變得更復雜)?
以上問題,如果都通過臨時修改代碼 (全域替換或加注釋) 來實作,則代碼將變得不可維護,事實上,由于代碼的無限可能性,甲寫的代碼乙很難理解,為解決上述問題,必須要有一套程式框架,而框架本身的撰寫、配置和使用又成了問題,
有沒有一種方法,不需要使用編程語言,而又能靈活滿足復雜的需求呢?
四、類編程的WAF
天存資訊的類編程 WAF,用資料結構來表達程式思想,讓普通的技術支持人員也能夠寫出足夠復雜和靈活的安全策略,
{
"if": {
"variables": "ARGS",
"transform": "urlDecodeUni",
"operator": "detectSQLi"
},
"then": {
"verdict": {
"action": "block",
"log": true
}
}
}
可見,這時的“規則”已經不是一行文本了,而是具有代碼特征的一個函式實作 ,
類編程的 WAF 具有以下與編程語言相似的特性:
- 無限嵌套的 if / the / else 條件判斷
- 完整的 and / or / not 邏輯運算子
- 對集合 / 陣列成員的遍歷運算
- 變數包含多種資料型別
- 支持變數的宏擴展參考
- 用戶自定義變數和運算式賦值
- 預置及可設定不同生命期的全域變數
- 用戶書寫任意多樣的動作
- 函式回傳值靈活控制流程
- 運行時改變其他函式行為
而這靈活內涵的表面,卻能夠用規范的模式 (schema) 來約束,使得寫出的類程式易讀且統一,甚至做到可視化呈現,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/288074.html
標籤:其他
上一篇:動態規劃之矩陣連乘
