調整 Azure Front Door 的 Azure Web 應用程式防火牆
Microsoft 管理的預設規則集是以 OWASP 核心規則集 為基礎, 並包含 Microsoft 威脅情報收集規則。
通常預期 Web 應用程式防火牆 (WAF) 規則必須經過微調,以符合使用 WAF 的應用程式或組織的特定需求。 組織通常會採取下列其中一項動作來達成調整:
- 定義規則排除專案。
- 建立自訂規則。
- 停用可能導致問題或誤判的規則。
本文說明如果應該通過 WAF 的要求遭到封鎖,您可以執行哪些動作。
注意
Microsoft 管理的規則集不適用於 Azure Front Door 標準 SKU。 如需不同層級 SKU 的詳細資訊,請參閱 各層 之間的功能比較。
閱讀 Azure Front Door WAF 概觀 和 適用于 Azure Front Door 檔的 WAF 原則。 此外,啟用 WAF 監視和記錄 。 這些文章說明 WAF 的運作方式、WAF 規則集的運作方式,以及如何存取 WAF 記錄。
瞭解 WAF 記錄
WAF 記錄的目的是要顯示 WAF 所比對或封鎖的每個要求。 這是符合或封鎖之所有已評估要求的集合。 如果您注意到 WAF 會封鎖它不應該的要求(誤判為真),您可以執行一些動作。
首先,縮小範圍並尋找特定要求。 您可以 設定自訂回應訊息 以包含 trackingReference
欄位,以輕鬆地識別事件,並針對該特定值執行記錄查詢。 查看記錄以尋找要求的特定 URI、時間戳記或用戶端 IP。 當您找到相關的記錄專案時,您可以對誤判採取行動。
例如,假設您有合法的流量,其中包含您想要通過 WAF 的字串 1=1
。 以下是要求的外觀:
POST http://afdwafdemosite.azurefd.net/api/Feedbacks HTTP/1.1
Host: afdwafdemosite.azurefd.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
UserId=20&captchaId=7&captchaId=15&comment="1=1"&rating=3
如果您嘗試要求,WAF 會封鎖任何參數或欄位中包含字串 1=1
的流量。 此字串通常與 SQL 插入式攻擊相關聯。 您可以查看記錄,並查看要求的時間戳記,以及封鎖或比對的規則。
下列範例顯示根據規則比對所產生的記錄專案。 您可以使用下列 Log Analytics 查詢來尋找在過去 24 小時內封鎖的要求。
AzureDiagnostics
| where Category == 'FrontDoorWebApplicationFirewallLog'
| where TimeGenerated > ago(1d)
| where action_s == 'Block'
AzureDiagnostics
| where Category == 'FrontdoorWebApplicationFirewallLog'
| where TimeGenerated > ago(1d)
| where action_s == 'Block'
在 requestUri
欄位中,您可以看到已特別提出 /api/Feedbacks/
要求。 進一步尋找欄位中的規則識別碼 942110
ruleName
。 瞭解規則識別碼,您可以移至 OWASP ModSecurity Core 規則集官方存放庫 ,然後依該 規則識別碼 搜尋以檢閱其程式碼,並瞭解此規則的相符專案。
然後,藉由檢查 action
欄位,您可以看到此規則已設定為在比對時封鎖要求。 您可以確認 WAF 已封鎖要求,因為 policyMode
已將 設定為 prevention
。
現在,請檢查欄位中的資訊 details
。 此欄位是您可以看到 matchVariableName
和 matchVariableValue
資訊的位置。 因為 Web 應用程式欄位中有人輸入 1=1
comment
,因此觸發此規則。
{
"time": "2020-09-24T16:43:04.5422943Z",
"resourceId": "/SUBSCRIPTIONS/<Subscription ID>/RESOURCEGROUPS/<Resource Group Name>/PROVIDERS/MICROSOFT.CDN/PROFILES/AFDWAFDEMOSITE",
"category": "FrontDoorWebApplicationFirewallLog",
"operationName": "Microsoft.Cdn/Profiles/WebApplicationFirewallLog/Write",
"properties": {
"clientIP": "1.1.1.1",
"clientPort": "53566",
"socketIP": "1.1.1.1",
"requestUri": "http://afdwafdemosite.azurefd.net:80/api/Feedbacks/",
"ruleName": "DefaultRuleSet-1.0-SQLI-942110",
"policy": "AFDWAFDemoPolicy",
"action": "Block",
"host": "afdwafdemosite.azurefd.net",
"trackingReference": "0mMxsXwAAAABEalekYeI4S55qpi5R7R0/V1NURURHRTA4MTIAZGI4NGQzZDgtNWQ5Ny00ZWRkLTg2ZGYtZDJjNThlMzI2N2I4",
"policyMode": "prevention",
"details": {
"matches": [
{
"matchVariableName": "PostParamValue:comment",
"matchVariableValue": "\"1=1\""
}
],
"msg": "SQL Injection Attack: Common Injection Testing Detected",
"data": "Matched Data: \"1=1\" found within PostParamValue:comment: \"1=1\""
}
}
}
{
"time": "2020-09-24T16:43:04.5422943Z",
"resourceId": "/SUBSCRIPTIONS/<Subscription ID>/RESOURCEGROUPS/<Resource Group Name>/PROVIDERS/MICROSOFT.NETWORK/FRONTDOORS/AFDWAFDEMOSITE",
"category": "FrontdoorWebApplicationFirewallLog",
"operationName": "Microsoft.Network/FrontDoor/WebApplicationFirewallLog/Write",
"properties": {
"clientIP": "1.1.1.1",
"clientPort": "53566",
"socketIP": "1.1.1.1",
"requestUri": "http://afdwafdemosite.azurefd.net:80/api/Feedbacks/",
"ruleName": "DefaultRuleSet-1.0-SQLI-942110",
"policy": "AFDWAFDemoPolicy",
"action": "Block",
"host": "afdwafdemosite.azurefd.net",
"trackingReference": "0mMxsXwAAAABEalekYeI4S55qpi5R7R0/V1NURURHRTA4MTIAZGI4NGQzZDgtNWQ5Ny00ZWRkLTg2ZGYtZDJjNThlMzI2N2I4",
"policyMode": "prevention",
"details": {
"matches": [
{
"matchVariableName": "PostParamValue:comment",
"matchVariableValue": "\"1=1\""
}
],
"msg": "SQL Injection Attack: Common Injection Testing Detected",
"data": "Matched Data: \"1=1\" found within PostParamValue:comment: \"1=1\""
}
}
}
檢查存取記錄也有價值,以擴充您對指定 WAF 事件的知識。 接下來,檢閱產生做為對上述事件的回應所產生的記錄。
您可以看到這些記錄是相關的,因為 trackingReference
值是相同的。 在提供一般見解的各種欄位中,例如 userAgent
和 clientIP
,請注意 httpStatusCode
和 httpStatusDetails
欄位。 在這裡,您可以看到用戶端收到 HTTP 403 回應,確認此要求遭到拒絕並遭到封鎖。
{
"time": "2020-09-24T16:43:04.5430764Z",
"resourceId": "/SUBSCRIPTIONS/<Subscription ID>/RESOURCEGROUPS/<Resource Group Name>/PROVIDERS/MICROSOFT.CDN/PROFILES/AFDWAFDEMOSITE",
"category": "FrontDoorAccessLog",
"operationName": "Microsoft.Cdn/Profiles/AccessLog/Write",
"properties": {
"trackingReference": "0mMxsXwAAAABEalekYeI4S55qpi5R7R0/V1NURURHRTA4MTIAZGI4NGQzZDgtNWQ5Ny00ZWRkLTg2ZGYtZDJjNThlMzI2N2I4",
"httpMethod": "POST",
"httpVersion": "1.1",
"requestUri": "http://afdwafdemosite.azurefd.net:80/api/Feedbacks/",
"requestBytes": "2160",
"responseBytes": "324",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36",
"clientIp": "1.1.1.1",
"socketIp": "1.1.1.1",
"clientPort": "53566",
"timeToFirstByte": "0.01",
"timeTaken": "0.011",
"securityProtocol": "",
"routingRuleName": "DemoBERoutingRule",
"rulesEngineMatchNames": [],
"backendHostname": "13.88.65.130:3000",
"isReceivedFromClient": true,
"httpStatusCode": "403",
"httpStatusDetails": "403",
"pop": "WST",
"cacheStatus": "CONFIG_NOCACHE"
}
}
{
"time": "2020-09-24T16:43:04.5430764Z",
"resourceId": "/SUBSCRIPTIONS/<Subscription ID>/RESOURCEGROUPS/<Resource Group Name>/PROVIDERS/MICROSOFT.NETWORK/FRONTDOORS/AFDWAFDEMOSITE",
"category": "FrontdoorAccessLog",
"operationName": "Microsoft.Network/FrontDoor/AccessLog/Write",
"properties": {
"trackingReference": "0mMxsXwAAAABEalekYeI4S55qpi5R7R0/V1NURURHRTA4MTIAZGI4NGQzZDgtNWQ5Ny00ZWRkLTg2ZGYtZDJjNThlMzI2N2I4",
"httpMethod": "POST",
"httpVersion": "1.1",
"requestUri": "http://afdwafdemosite.azurefd.net:80/api/Feedbacks/",
"requestBytes": "2160",
"responseBytes": "324",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36",
"clientIp": "1.1.1.1",
"socketIp": "1.1.1.1",
"clientPort": "53566",
"timeToFirstByte": "0.01",
"timeTaken": "0.011",
"securityProtocol": "",
"routingRuleName": "DemoBERoutingRule",
"rulesEngineMatchNames": [],
"backendHostname": "13.88.65.130:3000",
"isReceivedFromClient": true,
"httpStatusCode": "403",
"httpStatusDetails": "403",
"pop": "WST",
"cacheStatus": "CONFIG_NOCACHE"
}
}
解決誤判
若要做出有關處理誤判的明智決策,請務必熟悉應用程式所使用的技術。 例如,假設您的技術堆疊中沒有 SQL 伺服器,而且您收到與這些規則相關的誤判。 停用這些規則不一定會削弱您的安全性。
利用這項資訊,而且規則 942110 是符合 1=1
範例中字串的知識,您可以執行一些動作來阻止此合法要求遭到封鎖:
- 使用排除清單。 如需排除清單的詳細資訊,請參閱 使用 Azure Front Door 排除清單 的 Azure Web 應用程式防火牆。
- 變更 WAF 動作。 如需當要求符合規則條件時可以採取哪些動作的詳細資訊,請參閱 WAF 動作 。
- 使用自訂規則。 如需自訂規則的詳細資訊,請參閱 使用 Azure Front Door 的 Azure Web 應用程式防火牆自訂規則。
- 停用規則。
提示
當您選取允許透過 WAF 的合法要求的方法時,請嘗試盡可能縮小。 例如,使用排除清單比完全停用規則更好。
使用排除清單
使用排除清單的其中一個優點是,只會檢查您選取排除的相符變數將不再檢查該指定要求。 也就是說,您可以在特定要求標頭、要求 Cookie、查詢字串引數或要求本文 post 引數之間做選擇,以在符合特定條件時排除,而不是排除要檢查的整個要求。 要求的其他未指定變數會正常檢查。
排除專案是全域設定。 設定的排除會套用至通過 WAF 的所有流量,而不只是特定的 Web 應用程式或 URI。 例如,如果 1=1
是特定 Web 應用程式主體中的有效要求,但對於相同 WAF 原則下的其他應用程式而言,這可能是一個顧慮。
如果對不同的應用程式使用不同的排除清單是合理的,請考慮針對每個應用程式使用不同的 WAF 原則,並將其套用至每個應用程式的前端。
當您設定 Managed 規則的排除清單時,您可以選擇排除:
- 規則集內的所有規則。
- 規則群組中的所有規則。
- 個別規則。
您可以使用 PowerShell 、Azure CLI 、REST API 、 Bicep、 Azure Resource Manager 範本或Azure 入口網站來設定排除清單 。
- 規則層級的排除專案: 在規則層級套用排除專案表示不會針對該個別規則分析指定的排除專案。 規則集中的所有其他規則仍會加以分析。 這是排除專案最細微的層級。 您可以使用它,根據您在 WAF 記錄中找到的資訊,微調受控規則集,當您針對事件進行疑難排解時。
- 規則群組層級的排除: 在規則群組層級套用排除專案表示不會針對該特定規則類型集分析指定的排除專案。 例如,選取 SQLI 做為排除規則群組,表示任何 SQLI 特定規則都不會檢查定義的要求排除專案。 它仍會由其他群組中的規則檢查,例如 PHP 、 RFI 或 XSS 。 當您確定應用程式不會受到特定類型的攻擊時,這種類型的排除可能會很有用。 例如,沒有任何 SQL 資料庫的應用程式可能會排除所有 SQLI 規則,而不會危害其安全性層級。
- 規則集層級的排除專案: 在規則集層級套用排除專案,表示不會根據該規則集中任何可用的安全性規則來分析指定的排除專案。 此排除是完整的,因此請小心使用。
在此範例中,您會將排除專案套用至單一規則,以最細微的層級執行排除。 您想要排除相符變數 要求本文後包含 的引數名稱 comment
。 您可以在防火牆記錄檔中看到相符變數詳細資料: "matchVariableName": "PostParamValue:comment"
。 屬性為 comment
。 您也可以透過其他幾種方式找到此屬性名稱。 如需詳細資訊,請參閱 尋找要求屬性名稱 。
有時候,在某些情況下,特定參數會以可能不直覺的方式傳入 WAF。 例如,當您使用 Microsoft Entra ID 進行驗證時,會傳遞權杖。 權杖 __RequestVerificationToken
通常會以要求 Cookie 的形式傳入。
在某些情況下,Cookie 已停用,此權杖也會以要求 post 引數的形式傳入。 基於這個理由,若要解決 Microsoft Entra 權杖誤判,您必須確定 __RequestVerificationToken
已新增至 和 RequestBodyPostArgsNames
的 RequestCookieNames
排除清單。
功能變數名稱上的排除專案 ( Selector ) 表示 WAF 將不再評估該值。 功能變數名稱本身會繼續評估,而且在極少數情況下,它可能會符合 WAF 規則並觸發動作。
變更 WAF 動作
處理 WAF 規則行為的另一種方式是選擇要求符合規則條件時所採取動作。 可用的動作為 [允許]、[封鎖]、[記錄] 和 [重新導向 ]。
在此範例中,預設動作 [封鎖 ] 已變更為 規則 942110 上的 [記錄 ] 動作。 此動作會導致 WAF 記錄要求,並繼續針對其餘較低優先順序規則評估相同的要求。
執行相同的要求之後,您可以參考記錄,並查看此要求與規則識別碼 942110 相符。 欄位 action_s
現在表示 [記錄檔 ] 而非 [ 封鎖 ]。 然後展開記錄查詢以 trackingReference_s
包含資訊,以查看此要求發生的其他狀況。
現在您可以看到處理規則識別碼 942110 之後發生的毫秒不同的 SQLI 規則比對。 規則識別碼 942310 上相符的相同要求,這次觸發了預設動作 [封鎖 ]。
在 WAF 微調或疑難排解期間使用 記錄 動作的另一個優點是,您可以識別特定規則群組內的多個規則是否比對並封鎖指定的要求。 然後,您可以在適當的層級建立排除專案,也就是規則或規則群組層級。
使用自訂規則
識別造成 WAF 規則相符的專案之後,您可以使用自訂規則來調整 WAF 回應事件的方式。 自訂規則會在 Managed 規則之前處理。 它們可以包含多個條件,而且其動作可以是 Allow、Deny、Log 或 Redirect 。
警告
當要求符合自訂規則時,WAF 引擎會停止處理要求。 此要求不會處理受控規則,其他優先順序較低的自訂規則也不會處理。
下列範例顯示具有兩個條件的自訂規則。 第一個條件會尋找 comment
要求本文中的值。 第二個條件會尋找 /api/Feedbacks/
要求 URI 中的值。
藉由使用自訂規則,您可以最細微,以便微調 WAF 規則並處理誤判。 在此情況下,您不會只根據 comment
要求本文值採取動作,這些值可能存在於相同 WAF 原則下的多個網站或應用程式。
當您包含另一個條件來同時符合特定要求 URI /api/Feedbacks/
時,您可確保此自訂規則確實適用于您審查的這個明確使用案例。如此一來,如果針對不同的條件執行相同的攻擊,WAF 引擎仍會檢查並防止攻擊。
當您探索記錄檔時,您可以看到 ruleName_s
欄位包含指定給自訂規則 redirectcomment
的名稱。 在 action_s
欄位中,您可以看到 已針對此事件採取重新導向 動作。 在 details_matches_s
欄位中,您可以看到這兩個條件的詳細資料都相符。
停用規則
另一個繞開誤判的方法,是停用符合 WAF 所認為惡意輸入的規則。 因為您已剖析 WAF 記錄,並將規則縮小至 942110,因此您可以在Azure 入口網站中將其停用。 如需詳細資訊,請參閱 使用 Azure 入口網站 自訂 Azure Web 應用程式防火牆 規則。
當您確定符合特定條件的所有要求都是合法的要求,或當您確定規則不適用於您的環境時,停用規則是一個好處(例如停用 SQL 插入規則,因為您有非 SQL 後端)。
停用規則是套用至與 WAF 原則相關聯之所有前端主機的全域設定。 當您選擇停用規則時,可能會讓弱點暴露,而不會針對與 WAF 原則相關聯的任何其他前端主機進行保護或偵測。
如果您想要使用 Azure PowerShell 來停用受控規則,請參閱 PSAzureManagedRuleOverride
目的檔。 如果您想要使用 Azure CLI,請參閱 az network front-door waf-policy managed-rules override
檔。
提示
記錄您對 WAF 原則所做的任何變更。 包含範例要求,以說明誤判偵測。 說明您為何新增自訂規則、停用規則或規則集,或新增例外狀況。 如果您在未來重新設計應用程式,您可能需要確認變更是否仍然有效。 或者,您可能會受到稽核或需要證明為何從其預設設定重新設定 WAF 原則。
尋找要求欄位
藉由使用 Fiddler 之類的 瀏覽器 Proxy,您可以檢查個別要求,並判斷呼叫網頁的特定欄位。 當您需要使用 WAF 中的排除清單,將特定欄位排除在檢查中時,這項技術會很有説明。
尋找要求屬性名稱
在此範例中,輸入字串的 1=1
欄位稱為 comment
。 此資料是在 POST 要求的主體中傳遞的。
您可以排除此欄位。 若要深入瞭解排除清單,請參閱 Web 應用程式防火牆排除清單 。 您可以藉由設定下列排除專案來排除此案例中的評估:
您也可以檢查防火牆記錄,以取得資訊,以查看您需要新增至排除清單的內容。 若要啟用記錄,請參閱 監視 Azure Front Door 中的計量和記錄。
檢查檔案中的 PT1H.json
防火牆記錄檔,以取得您想要檢查的要求發生的時間。 檔案 PT1H.json
可在儲存體帳戶容器中取得,其中 FrontDoorWebApplicationFirewallLog
會儲存 和 FrontDoorAccessLog
診斷記錄。
檢查檔案中的 PT1H.json
防火牆記錄檔,以取得您想要檢查的要求發生的時間。 檔案 PT1H.json
可在儲存體帳戶容器中取得,其中 FrontdoorWebApplicationFirewallLog
會儲存 和 FrontdoorAccessLog
診斷記錄。
在此範例中,您可以看到封鎖要求的規則(具有相同的交易參考),以及同時發生的規則。
{
"time": "2020-09-24T16:43:04.5422943Z",
"resourceId": "/SUBSCRIPTIONS/<Subscription ID>/RESOURCEGROUPS/<Resource Group Name>/PROVIDERS/MICROSOFT.CDN/PROFILES/AFDWAFDEMOSITE",
"category": "FrontDoorWebApplicationFirewallLog",
"operationName": "Microsoft.Cdn/Profiles/WebApplicationFirewallLog/Write",
"properties": {
"clientIP": "1.1.1.1",
"clientPort": "53566",
"socketIP": "1.1.1.1",
"requestUri": "http://afdwafdemosite.azurefd.net:80/api/Feedbacks/",
"ruleName": "DefaultRuleSet-1.0-SQLI-942110",
"policy": "AFDWAFDemoPolicy",
"action": "Block",
"host": "afdwafdemosite.azurefd.net",
"trackingReference": "0mMxsXwAAAABEalekYeI4S55qpi5R7R0/V1NURURHRTA4MTIAZGI4NGQzZDgtNWQ5Ny00ZWRkLTg2ZGYtZDJjNThlMzI2N2I4",
"policyMode": "prevention",
"details": {
"matches": [
{
"matchVariableName": "PostParamValue:comment",
"matchVariableValue": "\"1=1\""
}
],
"msg": "SQL Injection Attack: Common Injection Testing Detected",
"data": "Matched Data: \"1=1\" found within PostParamValue:comment: \"1=1\""
}
}
}
{
"time": "2020-09-24T16:43:04.5422943Z",
"resourceId": "/SUBSCRIPTIONS/<Subscription ID>/RESOURCEGROUPS/<Resource Group Name>/PROVIDERS/MICROSOFT.NETWORK/FRONTDOORS/AFDWAFDEMOSITE",
"category": "FrontdoorWebApplicationFirewallLog",
"operationName": "Microsoft.Network/FrontDoor/WebApplicationFirewallLog/Write",
"properties": {
"clientIP": "1.1.1.1",
"clientPort": "53566",
"socketIP": "1.1.1.1",
"requestUri": "http://afdwafdemosite.azurefd.net:80/api/Feedbacks/",
"ruleName": "DefaultRuleSet-1.0-SQLI-942110",
"policy": "AFDWAFDemoPolicy",
"action": "Block",
"host": "afdwafdemosite.azurefd.net",
"trackingReference": "0mMxsXwAAAABEalekYeI4S55qpi5R7R0/V1NURURHRTA4MTIAZGI4NGQzZDgtNWQ5Ny00ZWRkLTg2ZGYtZDJjNThlMzI2N2I4",
"policyMode": "prevention",
"details": {
"matches": [
{
"matchVariableName": "PostParamValue:comment",
"matchVariableValue": "\"1=1\""
}
],
"msg": "SQL Injection Attack: Common Injection Testing Detected",
"data": "Matched Data: \"1=1\" found within PostParamValue:comment: \"1=1\""
}
}
}
透過您瞭解 Azure 受控規則集的運作方式,您知道具有 action: Block
屬性的規則會根據要求本文中相符的資料來封鎖。 (如需詳細資訊,請參閱 Azure Front Door 中的 Azure Web 應用程式防火牆。您可以在詳細資料中看到它符合模式 ( 1=1
) 且欄位命名為 comment
。 請遵循相同的先前步驟來排除包含 comment
的要求本文後置 args 名稱。
尋找要求標頭名稱
Fiddler 是尋找要求標頭名稱的公用程式。 下列螢幕擷取畫面顯示此 GET 要求的標頭,其中包含 Content-Type
和 User-Agent
。 您也可以使用要求標頭在 WAF 中建立排除專案和自訂規則。
另一個檢視要求和回應標頭的方式是查看瀏覽器的開發人員工具,例如 Microsoft Edge 或 Chrome。 您可以選取 F12,或以滑鼠右鍵按一下 [ 檢查 > 開發人員工具]。 選取 [ 網路 ] 索引標籤。載入網頁,然後選取您要檢查的要求。
尋找要求 Cookie 名稱
如果要求包含 Cookie,請選取 [Cookie] 索引標籤,以在 Fiddler 中檢視它們。 Cookie 資訊也可以用來在 WAF 中建立排除專案或自訂規則。
異常評分規則
如果您在調整 WAF 的過程中看到規則識別碼 949110,其存在表示要求遭到 異常評分 程式封鎖。
搜尋具有相同追蹤參考的記錄專案,以檢閱相同要求的其他 WAF 記錄專案。 查看觸發的每個規則。 遵循本文中的指引來調整每個規則。
下一步
- 瞭解 Azure Web 應用程式防火牆 。
- 瞭解如何 建立 Azure Front Door 的實例。