分享方式:


調整適用於 Azure Front Door 的 Azure Web 應用程式防火牆

Microsoft 管理的預設規則集是以 OWASP 核心規則集為基礎,並包含 Microsoft 威脅情報收集規則。

通常預期必須微調 Web 應用程式防火牆 (WAF) 規則,才能符合使用 WAF 的應用程式或組織的特定需求。 組織通常會採取下列其中一項動作來實現調整:

  • 定義規則排除項目。
  • 建立自訂規則。
  • 停用可能導致問題或誤判為真的規則。

本文描述如果應該通過 WAF 的要求遭到封鎖,您可以執行哪些動作。

注意

Microsoft 管理的規則集不適用於 Azure Front Door 標準 SKU。 如需不同階層 SKU 的詳細資訊,請參閱階層之間的功能比較

閱讀 Front Door WAF 概觀Azure Front Door 的 WAF 原則文件。 另外,啟用 Azure 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/ 提出的要求。 接下來,在 ruleName 欄位中尋找規則識別碼 942110。 知道規則識別碼後,您可以移至 OWASP ModSecurity 核心規則集官方存放庫,並依該規則識別碼搜尋,檢閱其程式碼,並確切了解此規則符合的內容。

然後,藉由檢查 action 欄位,您可以看到此規則已設定為比對時封鎖要求。 您可以確認 WAF 已封鎖要求,因為 policyMode 設定為 prevention

現在,檢查 details 欄位中的資訊。 您可以在此欄位中看到 matchVariableNamematchVariableValue 資訊。 因為有人在 Web 應用程式的 comment 欄位中輸入 1=1,所以觸發了此規則。

{
    "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 值相同。 在提供一般深入解析的各種欄位中,如 userAgentclientIP,請注意 httpStatusCodehttpStatusDetails 欄位。 在這裡,您可以看到用戶端收到 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 字串,您就可以採取一些措施,防止此合法要求遭到封鎖:

提示

選取方法以透過 WAF 允許合法要求時,請嘗試盡可能縮小範圍。 例如,使用排除清單比完全停用規則更好。

使用排除清單

使用排除清單的其中一個優點是,只不會再針對該指定要求,檢查您選取要排除的比對變數。 也就是說,您可以選擇特定要求標頭、要求 Cookie、查詢字串引數或要求本文 post 引數,以在符合特定條件時排除,而不是將整個要求排除在檢查之外。 系統仍會正常檢查要求的其他非指定變數。

排除是一種全域設定。 設定的排除會套用至通過 WAF 的所有流量,而不只是特定 Web 應用程式或 URI。 舉例來說,如果 1=1 是特定 Web 應用程式本文中的有效要求,可能會是問題,但對於相同 WAF 原則下的其他人而言並非如此。

如果可對不同應用程式使用不同排除清單,請考慮針對每個應用程式使用不同 WAF 原則,並將原則套用至每個應用程式的前端。

設定受控規則的排除清單時,您可以選擇排除:

  • 規則集內的所有規則。
  • 規則群組內的所有規則。
  • 個別規則。

您可以使用 PowerShellAzure CLIREST API、Bicep、Azure Resource Manager 範本或 Azure 入口網站來設定排除清單。

  • 規則層級的排除:在規則層級套用排除,表示將不會只針對該個別規則分析指定的排除。 規則集中的所有其他規則仍會對其進行分析。 這是排除的最細微層級。 您可以使用該層級,在針對事件進行疑難排解時,根據您在 WAF 記錄中找到的資訊,微調受控規則集。
  • 規則群組層級的排除:在規則群組層級套用排除,表示將不會針對該特定的規則類型集,分析指定的排除。 例如,選取 SQLI 當作排除的規則群組,表示任何 SQLI 特定規則都不會檢查定義的要求排除。 其他群組中的規則仍會對其進行檢查,例如 PHPRFIXSS。 當您確定應用程式不易受到特定類型攻擊時,這類排除可能很有用。 例如,沒有任何 SQL 資料庫的應用程式可能會排除所有 SQLI 規則,不會危害其安全性層級。
  • 規則集層級的排除:在規則集層級套用排除,表示將不會針對該規則集中可用的任何安全性規則,分析指定的排除。 此排除是全面的,因此請小心使用。

在此範例中,您會將排除套用至單一規則,以在最細微的層級執行排除。 您想要排除比對變數要求本文 Post 引數名稱,其中包含 comment。 您可以在防火牆記錄中看到比對變數詳細資料:"matchVariableName": "PostParamValue:comment"。 屬性為 comment。 您也可以透過其他幾種方式尋找此屬性名稱。 如需詳細資訊,請參閱尋找要求屬性名稱

顯示排除規則的螢幕擷取畫面。

顯示特定規則規則排除的螢幕擷取畫面。

有時,特定參數會以可能不直覺的方式傳遞至 WAF。 例如,使用 Microsoft Entra ID 進行驗證時會傳遞權杖。 權杖 __RequestVerificationToken 通常會以要求 Cookie 的形式傳遞。

在某些停用 Cookie 的情況下,此權杖也會以要求 Post 引數的形式傳遞。 基於這個理由,若要解決 Microsoft Entra 權杖誤判為真,您必須確保 __RequestVerificationToken 新增至 RequestCookieNamesRequestBodyPostArgsNames 的排除清單。

欄位名稱 ([選取器]) 上的排除表示 WAF 將不再評估此值。 欄位名稱本身會繼續進行評估,且在極少數情況下,可能會比對 WAF 規則並觸發動作。

顯示規則集規則排除的螢幕擷取畫面。

變更 WAF 動作

另一種處理 WAF 規則行為的方式,是選擇要求符合規則條件時採取的動作。 可用的動作為允許、封鎖、記錄和重新導向

在此範例中,預設動作 [封鎖] 已變更為規則 942110 上的 [記錄] 動作。 此動作會導致 WAF 記錄要求,並繼續針對其餘優先順序較低的規則評估相同要求。

顯示 WAF 動作的螢幕擷取畫面。

在執行相同的要求之後,您可以再次參考記錄,並看到此要求符合規則識別碼 942110。 action_s 欄位現在表示 [記錄] ,而不是 [封鎖]。 記錄查詢接著展開以包含 trackingReference_s 資訊,來查看此要求發生的其他情況。

顯示顯示多個規則相符項目的記錄的螢幕擷取畫面。

現在您可以看到在處理規則識別碼 942110 之後幾毫秒發生的不同 SQLI 規則比對。 相同要求符合規則識別碼 942310,這次觸發預設動作 [封鎖]

在 WAF 微調或疑難排解期間使用 [記錄] 動作的另一個優點是,您可以識別特定規則群組內的多個規則是否在比對並封鎖指定要求。 您接著可以在適當層級,亦即規則或規則群組層級,建立排除。

使用自訂規則

在識別了造成 WAF 規則相符的項目之後,您可以使用自訂規則,調整 WAF 回應事件的方式。 自訂規則會在受控規則之前進行處理。 其可以包含多個條件,而且其動作可為允許、拒絕、記錄或重新導向

警告

當要求符合自訂規則時,WAF 引擎會停止處理要求。 受控規則將不會針對此要求進行處理,而其他優先順序較低的自訂規則也不會。

下列範例說明具有兩個條件的自訂規則。 第一個條件會在要求本文中尋找 comment 值。 第二個條件會在要求 URI 中尋找 /api/Feedbacks/ 值。

藉由使用自訂規則,您可以是最細微的,以便可以微調 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 原則進行的任何變更。 包含範例要求,以說明誤判為真偵測。 說明您為何新增了自訂規則、停用了規則或規則集,或新增了例外狀況。 如果您未來重新設計應用程式,則可能需要驗證您的變更是否仍然有效。 或者,您可能會受到稽核,或必須證明為何從預設設定重新設定 WAF 原則。

尋找要求欄位

透過使用 Fiddler 等瀏覽器 Proxy,您可以檢查個別要求,並確定呼叫網頁的哪些特定欄位。 當您必須使用 WAF 中的排除清單,從檢查中排除特定欄位時,這個技巧很有用。

尋找要求屬性名稱

在此範例中,輸入 1=1 字串的欄位稱為 comment。 此資料是以 POST 要求的本文傳遞。

顯示 Fiddler 要求本文的螢幕擷取畫面。

您可以排除此欄位。 若要深入了解排除清單,請參閱 Web 應用程式防火牆排除清單。 您可以設定以下排除來排除此案例中的評估:

顯示一個排除規則的螢幕擷取畫面。

您也可以檢查防火牆記錄以取得資訊,了解您須新增至排除清單的內容。 若要啟用記錄,請參閱監視 Azure Front Door 中的計量和記錄

檢查 PT1H.json 檔案中防火牆記錄,查看您想要檢查的要求發生的時間。 在儲存 FrontDoorWebApplicationFirewallLogFrontDoorAccessLog 診斷記錄的儲存體帳戶容器中,可取得 PT1H.json 檔案。

檢查 PT1H.json 檔案中防火牆記錄,查看您想要檢查的要求發生的時間。 在儲存 FrontdoorWebApplicationFirewallLogFrontdoorAccessLog 診斷記錄的儲存體帳戶容器中,可取得 PT1H.json 檔案。

在此範例中,您可以看到已封鎖要求 (具有相同交易參考) 且同時發生的規則。

{
    "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 的要求本文 post 引數名稱。

尋找要求標頭名稱

Fiddler 是尋找要求標頭名稱的實用工具。 下列螢幕擷取畫面顯示此 GET 要求的標頭,其中包含 Content-TypeUser-Agent。 您也可以使用要求標頭,在 WAF 中建立排除和自訂規則。

顯示 Fiddler 要求標頭的螢幕擷取畫面。

另一種檢視要求和回應標頭的方式,是查看瀏覽器 (例如 Microsoft Edge 或 Chrome) 的開發人員工具。 您可以選取 F12 或以滑鼠右鍵按一下 [檢查]>[開發人員工具]。 選取 [網路] 索引標籤。載入網頁,然後選取您想要檢查的要求。

顯示網路偵測器要求的螢幕擷取畫面。

如果要求包含 Cookie,請選取 [Cookie] 索引標籤,在 Fiddler 中加以檢視。 Cookie 資訊也可用來在 WAF 中建立排除或自訂規則。

異常評分規則

如果您在調整 WAF 的過程中看到規則識別碼 949110,其出現表示異常評分流程已封鎖要求。

您可以搜尋具有相同追蹤參考的記錄項目,來檢閱相同要求的其他 WAF 記錄項目。 查看已觸發的每個規則。 遵循本文中的指引來調整每個規則。

警告

將新的 Managed 規則集指派給 WAF 原則時,來自現有 Managed 規則集的所有先前自定義專案,例如規則狀態、規則動作和規則層級排除,都會重設為新的 Managed 規則集預設值。 不過,在新的規則集指派期間,任何自定義規則和原則設定都不會受到影響。

下一步