为 Azure Front Door 优化 Azure Web 应用程序防火墙

适用于: ✔️ Front Door 标准版/高级版

Microsoft托管的默认 规则集基于 OWASP 核心规则集 ,包括Microsoft威胁智能收集规则。

你经常需要根据应用或组织的具体需求调整网页应用防火墙(WAF)规则。 常见的调音动作包括:

  • 定义规则排除项。
  • 创建自定义规则。
  • 禁用导致问题或误报的规则。

本文描述了如果WAF阻止了本应通过的请求,你可以做些什么。

注释

Microsoft 管理的规则集不适用于 Azure Front Door 标准 SKU。 有关不同层 SKU 的详细信息,请参阅 层之间的功能比较

请阅读Azure Front Door WAF概述Azure Front Door WAF政策相关文章。 此外,启用 WAF 监视和日志记录。 这些文章介绍了 WAF 的工作原理、WAF 规则集的工作原理以及如何访问 WAF 日志。

在调整前了解政策范围的影响

在调整规则、排除项或操作之前,请确定你将该策略关联到的范围:

  • 配置文件级别:变更可能影响配置文件中所有受保护的流量。
  • 域级:变更会影响所选域关联的流量。
  • 路由级别:变更只影响匹配的路由,且是最有针对性的选项。

如果多个作用域适用于某个请求,则路由级策略优先于域级策略,而域级策略又优先于配置级策略。

对于大多数部署,建议先在配置集级别进行基线调优,再将例外项下沉到域级或路由级范围,以减少运维影响范围。

了解 WAF 日志

WAF日志的目的是显示WAF匹配或阻断的每一个请求。 日志会记录所有经过评估且被 WAF 匹配到或拦截的请求。 如果你发现 WAF 拦截了本不应被拦截的请求(误报),你可以采取以下几项措施。

首先,缩小范围并查找特定请求。 你可以 配置自定义响应消息 ,包含该 trackingReference 字段,这样你可以轻松识别事件并对该特定值进行日志查询。 查看日志以查找请求的特定 URI、时间戳或客户端 IP。 找到相关的日志条目时,可以针对误报采取措施。

例如,假设存在合法流量,其中包含字符串 1=1,而你希望这些流量通过 WAF。 下面是请求的示例:

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 查询,查找 WAF 在过去 24 小时内阻断的请求。

AzureDiagnostics
| where Category == 'FrontDoorWebApplicationFirewallLog'
| where TimeGenerated > ago(1d)
| where action_s == 'Block'

requestUri 字段中,您可以看到请求是专门发向 /api/Feedbacks/ 的。 接下来,在字段中查找规则 ID 942110ruleName 。 知道规则ID后,你可以访问 OWASP ModSecurity Core Rule Set的官方仓库 ,通过该规则ID搜索代码,查看代码,准确理解该规则在哪些地方匹配。

通过查看字段 action ,你可以看到该规则设置为在匹配时阻止请求。 你可以确认该请求被 WAF 阻止,因为 policyMode 已设置为 prevention

现在,请检查details字段中的信息。 此字段是可以查看 matchVariableNamematchVariableValue 信息的位置。 之所以触发此规则,是因为有人在 1=1 Web 应用的字段中输入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\""
        }
    }
}

检查访问日志也有助于加深你对特定 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"
    }
}

解决误报

若要做出有关处理误报的明智决策,请务必熟悉应用程序使用的技术。 例如,如果技术堆栈不包含 SQL Server,并且你收到与这些规则相关的误报,则禁用这些规则不一定会削弱安全性。

借助这些信息,并了解示例中与字符串 1=1 匹配的规则是 942110,您可以采取一些措施来阻止此合法请求被阻挡。

小窍门

选择允许合法请求通过 WAF 的方法时,请尝试让方法尽可能具体。 例如,最好使用排除列表而不是完全禁用规则。

使用排除列表

使用排除列表的一个好处是,WAF会停止检查你为该请求选择排除的匹配变量。 你可以选择特定的请求标头、请求 Cookie、查询字符串参数或请求正文中的 POST 参数,在满足特定条件时将其排除,而不是将整个请求排除在检测之外。 通常检查请求的其他未指定变量。

排除项是全局设置。 配置的排除项适用于通过 WAF 传递的所有流量,而不仅仅是特定的 Web 应用或 URI。 例如,如果 1=1 在某个 Web 应用的请求体中属于有效请求,但对同一 WAF 策略下的其他应用而言并非如此,则这种情况可能会引发问题。

如果对不同的应用程序使用不同的排除列表是有意义的,请考虑为每个应用程序使用不同的 WAF 策略并将其应用到每个应用程序的前端。

为托管规则配置排除列表时,可以选择排除:

  • 规则集中的所有规则。
  • 规则组中的所有规则。
  • 单个规则。

可以使用 PowerShellAzure CLIREST API、Bicep、Azure 资源管理器模板或 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的操作的屏幕截图。

执行相同的请求后,可以引用日志,并看到此请求与规则 ID 942110 匹配。 该 action_s 字段现在指示 “日志 ”而不是 “阻止”。 然后将日志查询扩展为包括 trackingReference_s 信息,以查看此请求的其他情况。

显示多个规则匹配项的日志的屏幕截图。

现在,可以看到一个不同的 SQLI 规则匹配,该匹配在处理规则 ID 942110 后发生毫秒。 在规则 ID 942310 上匹配的相同请求,这次触发了默认操作阻止

在 WAF 优化或故障排除期间使用 日志 作的另一个优点是,可以确定特定规则组中的多个规则是否匹配并阻止给定的请求。 然后,可以在适当的级别(即规则或规则组级别)创建排除项。

使用自定义规则

确定导致WAF规则匹配的原因后,使用自定义规则调整WAF对事件的响应。 在托管规则之前处理自定义规则。 它们可以包含多个条件,其作可以是 “允许”、“拒绝”、“日志”或“重定向”。

警告

当请求与自定义规则匹配时,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 后端),则禁用规则是一个好处。

禁用某条规则会对该策略关联范围所评估的所有流量生效。 当你选择禁用某条规则时,可能会导致同一作用范围内的其他流量所涉及的漏洞在没有防护或检测的情况下暴露出来。

若要使用 Azure PowerShell 禁用托管规则,请参阅 PSAzureManagedRuleOverride 对象文档。 若要使用 Azure CLI,请参阅 az network front-door waf-policy managed-rules override 文档。

小窍门

记录对 WAF 策略所做的任何更改。 包括用于说明误报检测的示例请求。 说明为何添加了自定义规则、禁用了规则或规则集或添加了异常。 如果将来重新设计应用程序,可能需要验证更改是否仍然有效。 可能会接受审核,或者需要证明为什么重新配置 WAF 策略并更改其默认值。

查找请求字段

通过使用 Fiddler 等浏览器代理,可以检查各个请求并确定调用网页的特定字段。 当你需要使用 WAF 中的排除列表从检查中排除某些字段时,此方法非常有用。

查找请求属性名称

在这个例子中,输入 1=1 字符串的字段称为 comment。 这些数据会放在POST请求的正文中。

显示 Fiddler 请求正文的屏幕截图。

可以排除此字段。 若要了解有关排除列表的详细信息,请参阅 Web 应用程序防火墙排除列表。 可以通过配置以下排除项来排除此情况中的评估:

显示排除规则的屏幕截图。

你还可以查看防火墙日志,获取需要添加到排除列表的信息。 若要启用日志记录,请参阅 Azure Front Door 中的“监视指标和日志”。

查看PT1H.json文件中,在您希望检查的请求发生时一小时内的防火墙日志。 这些PT1H.json文件在存储FrontDoorWebApplicationFirewallLogFrontDoorAccessLog诊断日志的存储帐户容器中可用。 在此示例中,您可以看到阻止请求的规则(具有相同的事务引用)以及发生在同一时间的情况。

{
    "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\""
        }
    }
}

凭借你对 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 的过程中看到规则 ID 949110,则这表示请求被异常评分过程阻止。

通过搜索具有相同跟踪引用的日志条目来查看同一请求的其他 WAF 日志条目。 查看触发的每个规则。 按照本文中的指南优化每个规则。

在混合作用域部署中调整请求时,请在事件记录中注明生效的策略作用域(配置文件、域或路由)。 这有助于防止团队在添加或修改关联时于日后引发回归问题。

警告

当将新的托管规则集分配给WAF策略时,所有之前来自现有托管规则集的自定义,如规则状态、规则动作和规则级别排除,都会重置为新托管规则集的默认值。 然而,任何自定义规则和策略设置在新规则集分配期间都不受影响。

后续步骤