類程式設計的WAF(下)
一、程式語言的要素
天存資訊的iWall3應用防火牆是一種創新式的類程式設計 WAF,它包含了程式語言的一些基本要素。
1. 變數
iWall3 中廣義的變數包括報文變數、環境變數和使用者變數:報文變數和環境變數相當於程式語言中的常量或傳入的引數,使用者變數則是真正程式語言意義上的變數,即使用者可以自行建立、使用和維護變數。
2. 條件判斷
iWall3 支援程式語言標準的條件判斷:即可以包含無限巢狀的 if
- then
- else
條件,每個 if
條件又可以使用 and
- or
- not
邏輯運算子連線多個子條件。
3. 表示式
iWall3 支援與通用程式語言一致的表示式:表示式由常量、變數、運算子和內建函式組成,以模板字串方式內嵌書寫,可在條件判斷、變數賦值、模式匹配、日誌輸出等任意位置使用。
4. 語句
條件執行部分,iWall3 允許使用者書寫任意語句:這些語句不限於 WAF 常規的阻止訪問和記錄日誌,它可以實現更復雜的功能,如:改變其他規則的行為,修改 HTTP 報文的特定部分,輸出指定變數等。
二、資料方式的語言表達
天存資訊的 iWall3 包含了程式語言的設計思想,但獨創性地以資料方式呈現。
1. JSON格式
安全產品的使用者通常是非程式設計師,他們習慣於面對配置檔案而非一段程式碼。因此,iWall3 的配置依舊以規則檔案的形式出現,只是這裡的規則不是純文字格式,而是可以體現出層次結構的 JSON 格式。
- 充分利用 JSON 格式的名-值對 (物件) 和序列表 (陣列) 結構,將語言要素和業務邏輯用 JSON 格式表達出來,兼顧規則的人機可讀性和高度靈活性。
- JSON 格式的每個元素都具有明確的名 (name),這就給了書寫者一個基本的框架和自說明的引數指引,既方便了自己書寫規則,也便於其他人對規則的維護。
- iWall3 規則具有明確細緻的語法定義,從而能夠使用成熟的 JSON schema 方式來校驗 (validate) 規則的正確性,例如可以細緻檢查動作的必選引數、可選引數以及拼寫錯誤。
2. 規則結構
一個規則即為一個 if-then-else
結構,在 JSON 格式中表現為一個名為 if
的物件和一個名為 then
的物件,以及可選的一個名為 else
的物件——
- if - 變數經選擇和整形後,與表示式模式的運算進行匹配。支援用邏輯運算子連線多個條件。
- then - 匹配後執行的一般語句和裁決語句,還可以包含子
if-then
結構。 - else - 不匹配時執行的語句和可選的子
if-then
結構。
以下是規則的一個舉例:
{
"if": {
"variable": "REQUEST_FILENAME_EXT",
"operator": "inFromFile",
"pattern": "restricted_file_exts.lst"
},
"then": {
"if": {
"variable": "REMOTE_ADDR",
"operator": "begin",
"pattern": "192.168"
},
"then": {
"verdict": {
"log": true,
"action": "pass"
},
"actions": [{
"action": "alterArgGet",
"op": "set",
"name": "iwall_rule_id",
"value": "${RULE.id}"
}],
},
"else": {
"verdict": {
"log": true,
"action": "deny"
}
}
}
}
上述規則實現的功能為: 遇到訪問敏感檔案型別時,記錄日誌,並對不同訪問來源作不同響應:來自內網的,放行且將規則 id 作為引數傳給後端應用;來自外網的,則拒絕。
3. 自動迴圈
一般程式語言中都有名為 for
的迴圈語句,用來對可迭代資料進行逐個元素處理。HTTP 協議中的請求引數 (args)、頭 (header) 都是可迭代資料,在 iWall3 中表現為集合或者陣列的資料型別。如果按照程式語言的慣例,用 for
迴圈去顯式地獲取資料,會讓規則寫得很繁瑣。
iWall3 則實現了對可迭代變數型別的自動迴圈,只需列出變數名,即可自動進行迴圈迭代,簡化了書寫。而對於不需要參與迴圈的元素,也提供了成員篩選的手段,直接在變數名後列出白名單或黑名單成員即可。
{
"if": {
"variable": "REQUEST_COOKIES:!cnzz_*",
"transform": "urlDecodeUni",
"operator": "detectSQLi"
}
}
上述規則對請求 cookie 中的每個成員進行 SQL 注入檢查,但排除掉 cnzz_ 開頭的成員。
4. 動態修改
規則並非是靜態孤立的,它不僅可以自身執行動作,還可以在 HTTP 會話過程中去改變其他規則的屬性,稱為元屬性覆寫。元屬性覆寫功能實現了執行時的檢測和動作分離,通過動態調整其他規則的輸入和響應,滿足使用者複雜的需求。
{
"if": [{
"variable": "REQUEST_FILENAME",
"operator": "=",
"pattern": "admin.php"
},
{
"variable": "TIME.hour",
"operator": "<",
"pattern": "8"
}],
"then": {
"actions": [{
"action": "alterRuleMeta",
"rules": "10001,30001-30999",
"meta": {
"severity": "warning",
"abnormal_weight": 15
}
}]
}
}
上述規則的功能是: 在 0:00am-8:00am 這一時間段內訪問 admin.php 時,部分規則的緊急度將被設為 critical,異常權值則被設為 15。
三、針對HTTP協議的定製
天存資訊的 iWall3 的目標是實現 Web 應用防護,因此在語言設計上也有與 HTTP 協議密切相關的因素。
1. 資料型別
與程式語言中的變數一樣,iWall3 的變數也具有多種資料型別。其中有些資料型別是專門針對 HTTP 協議而設計的,如:
集合型別 | 結構型別 |
---|---|
允許同名的成員。HTTP 協議允許出現同名的請求引數和頭,用集合型別來體現名-值對而非鍵-值對。 | 允許使用 XPath 和 JsonPath 來指定元素,對 XML 和 JSON 型別的請求資料能夠更精細地處理。 |
2. 持久變數
iWall3 的使用者變數具有自己的生命期。在語言層面,iWall3 不僅提供了 HTTP 會話期內有效的事務內變數,也提供了跨越 HTTP 會話的持久變數。
持久變數提供了跨越 HTTP 事務的儲存、計算和讀取資料的機制。這樣,Web 應用防護的邏輯就不侷限於單個 HTTP 會話,而是可以在多個 HTTP 會話間建立聯絡。
3. 狀態維護
HTTP 協議本身是無狀態的,這意味著沒有“使用者”的概念。但在防護功能上,我們又需要有一個“使用者”的概念,這樣才能將多個 HTTP 事務關聯起來,制定針對“使用者”的防護措施。
iWall3 提供了主體的概念,它是 HTTP 事務的發起端和訪問者。對於每個 HTTP 事務,可以從裝置、網路和報文等不同層面採集資訊,得到多個型別的主體。如此,書寫者能夠對多個 HTTP 事務中的同一主體應用規則 (如長時間攔截) 和共享資料 (如權重計算)。
四、有什麼用
使用類程式設計 WAF,安全人員不再是規則的使用者,而變成了規則的生產者。針對應用的細緻和獨立的安全需求,基本上都可以用程式設計的方式實現出來,不再受限於 WAF 產品提供的內建功能。
如本文開頭所述的功能需求,即使僅僅在防範注入方面:
- 某個域名或某些特定的 URL 不需要注入檢查;
- 對來自外網的注入訪問進行攔截,來自內網的注入訪問只記錄,不攔截;
- 對特定的請求引數名或特定特徵的請求引數不進行注入檢查;
- 非工作時段不僅攔截還阻止該使用者一段時間訪問;
- 對 admin 等管理賬號登入後的訪問不進行注入檢查;
- 對於只記錄不攔截的請求,附加一個特別的請求頭髮往應用;
- 對某些 URL 的注入訪問,記錄下 HTTP 請求的全部報文;
- HTTP 響應碼為 500 的注入的日誌緊急度設為 alert;
- 對疑似的注入企圖不做一次攔截,而是進行加權計算。
無論是上述某一條還是更復雜的組合,安全人員都可以在使用者現場通過高度靈活的類程式設計 iWall3 來實現。