ESAPI WAF由XML策略文件驱动,该文件告诉应用程序在应用程序中执行哪些规则,这些规则可以做很多事情,从简单的虚拟补丁到使用BeanShell脚本复杂授权
该文档描述了策略文件的结构,每一个规则及其工作原理。这里也会提供一些示例去引导整个实验过程,下图直观展示了XSD策略文件,这里策略文件的正式规范
如图所示,策略文件的根元素是”policy”,并且没有任何属性。在”policy”根元素里面有很多规则标签,这些只是帮助组织策略文件的规则类别。如图所示,只有标签”aliases”和”settings”是必要的,考虑到这一点,下面是一个没有任何规则的框架示例
<?xml version="1.0" encoding="UTF-8"?>
<policy>
<aliases></aliases>
<settings>
<mode>block</mode>
<session-cookie-name>JSESSIONID</session-cookie-name>
<error-handling>
<default-redirect-page>/error.jsp</default-redirect-page>
<block-status>500</block-status>
</error-handling>
</settings>
</policy>
如果你正在编写自己的策略文件,从这个空文件开始是最好的选择。每一条规则都有一个可选的ID属性,可用于每个规则的唯一标识。虽然id属性也不是必须的,不过你可以在日志中搜索它,来发现具体触发了哪些规则。<p>
下面的内容即专门讨论上述的每个规则细节。
<aliases>
标签为在整个策略文件定义公用的字符串,该标签中可以用0个或多个<alias>子标签。
想象一下,在/admin目录中发现了若干漏洞,由于有很多规则会引用网站的这一部分,因此需要有一个配置来定义它。它减少了错误的规则,并有助于使规则更有条理。示例如下:
<aliases>
<alias name="ADMIN_PATH" type="regex">^/admin/.*</alias>
</aliases>
属性name
是必须的,用于之后在策略中引用的别名,所以应使用便于理解的单词。
属性type
是可选项,用于告诉WAF该字符串是一个JAVA正则表达式。若没有指定,默认为普通字符串,建议使用regex
<settings>
标签是WAF的全局配置,本节内容主要讲解了WAF的两个基本内容:WAF的运行模式和error-hadling执行。示例如下:
<settings>
<mode>redirect</mode>
<error-handling>
<default-redirect-page>/security/error.jsp</default-redirect-page>
<block-status>403</block-status>
</error-handling>
</settings>
<mode>
子标签<mode>
是必须的,mode
表示高等级该如何处理严重的安全事件。安全事件发生在某些规则与传入的请求相匹配时,例如,如果用户访问<virtual-patch>
规则时,应用应执行该模式配置的内容。然而,一条<add-header>
规则企图在每一个请求上触发,通常安全性的最佳实践是不依赖于其它操作。
Mode
有三个配置可选项:redirect,block,log。
<mode>log</mode>
当<mode>
配置为log
时,WAF仅执行记录日志,并且在安全规则被触发时不执行任何其它操作。此模式可用于测试生产环境中的规则,以便在短时间调整安全规则。设置<mode>
为其它任何值与设置成log相同,指定为log只是告诉WAF不要执行任何其它操作
<mode>redirect</mode>
当<mode>
配置为redirect时,应用程序会重定向至302或者JavaScript客户端重定向的错误页面,具体取决于触发规则时应用程序的状态。用户被重定向的目标URL配置在<error-handling>
标签中
<mode>block</mode>
当配置为block时,应用程序在发生严重的安全错误时会简单的停止处理请求,并且返回一个空响应
<session-cookie-name>
子标签<session-cookie-name>
是可选的,该值告诉WAF应用程序容器中session的cookie名称是什么,如果为空,则默认值为JSESSIONID。该标签尚为实验功能,不推荐使用。
<error-handling>
在该项中配置两个值:<default-redirect-page>
(默认重定向URL)和<block-status>
(状态值)。
<default-redirect-page>
配置的是WAF处于<mode>redirect</mode>
是发生严重安全事件后重定向的地址。它可以是一个相对或者绝对的URL地址,应用于客户端的302跳转和JavaScript中。建议将此值设置为通用错误页面
<block-status>
配置的是WAF处于<mode>block</mode>
发生严重安全事件时要使用的HTTP状态码,常见的值为:401,302和500。当mode为log或者redirect时,此值不起作用。
<authentication-rules>
标签允许WAF执行典型的J2EE认证请求。
典型的J2EE应用程序认证模式需确保session变量存在于某些基础action类中,如果该变量不存在,即表示该请求被认为是未经认证的并作适当的处理。但是,由于应用程序支持广泛的功能与服务,在保护所有需要认证的功能方面经常出现配置错误。
如果这种模式不能用于您的应用程序对用户进行认证操作,你可以不使用它。下面是一个<authentication-rules>
标签的使用实例,它保护应用程序所有的URL,除了一些公开的静态内容和首页:
<authentication-rules path="/.*" key="UserAuthKey" >
<path-exception>/</path-exception>
<path-exception>/index.html</path-exception>
<path-exception>/login.jsp</path-exception>
<path-exception>/index.jsp</path-exception>
<path-exception type="regex">/images/.*</path-exception>
<path-exception type="regex">/css/.*</path-exception>
<path-exception type="regex">/help/.*</path-exception>
</authentication-rules>
属性path
是必须的,告诉WAF哪些URL是需要经过认证的,属性值为正则表达式。在上述的实例中,path的值为/.*
,意思是对任何请求都将强制进行认证。
属性key
是必须的,告诉WAF应该检查存在的session
属性,如果此session
属性具有任何非空值,即表示该用户已认证。
<path-exception>
有很多规则可以嵌套在<path-exception>
中,意思是告诉WAF不要将给定的规则应用于特定的URL中,即白名单。如果该标签的type属性设置为”regex”,才解析以正则表达式形式出现的路径URL。这些路径通用应用于放行静态资源文件,和其它任何用户不用登陆就能访问到的页面。
<authorization-rules>
标签允许WAF执行典型的J2EE授权请求。该标签支持两种不同类型的规则:<restrict-source-ip>
和<must-match>
。
子标签
<restrict-source-ip>
大多数应用都有普通用户和管理员用户,由于它们部署在同一个应用程序中,普通用户可以访问管理员页面,只要保险公司能够得到正确的URL或者窃取管理员的cookie/session。
<restrict-source-ip>
规则通过IP限制对某些URL的访问来解决这个问题,通过这种方法有助于缩减暴露的管理员证书/登陆凭证带来的危害,允许颗粒度的网络策略来请求不同层次的应用程序。
<authorization-rules>
<restrict-source-ip
type="regex"
ip-header="X-ORIGINAL-IP"
ip-regex="(192\.168\.1\..*|127.0.0.1)">/admin/.*</restrict-source-ip>
</authorization-rules>
<restrict-source-ip>
规则允许访问/admin/.
的任何URL只能是本地局域网IP(192.168.1.*)或是服务器本身。
属性type
被设置为regex
,告诉WAF被保护的路径是正则表达式形式的字符串
属性ip-header
告诉WAF请求头将控制用户原始的IP地址,应用程序通常设置在一个或多个代理服务器的下游,这将掩盖请求的真实原始IP,这种情况下,应用通常会使用请求的真实IP填充请求头。在上述实例中,用户的IP地址可以在X-ORIGINAL-IP
中找到,若不指定该字段,默认在HttpServletRequest
对象中查找IP地址。
属性ip-regex
,应该包含一个正则表达式,当匹配到一个传入的请求IP时,即表明该请求已被授权。
<must-match>
<must-match>
规则是功能强大的标签,可以用来实现诸多不同的功能,特别是授权(基于角色的访问控制核查)
从技术上来讲必须<must-match>
规则是这样的:
在执行授权检查时,J2EE应用会在两个地方查询用户的角色:session或请求头。在下面的例子中,WAF将会在x-roles
的请求头中查找是否包含字符串admin
。
<authorization-rules>
<must-match
path="^/admin/.*"
variable="request.headers.X-ROLES"
operator="contains"
value="admin" />
</authorization-rules>
下面是一个备用的示例,当用户角色存储在org.acme.user.roles这个session变量中
<authorization-rules>
<must-match
path="^/admin/.*"
variable="session.org.acme.user.roles"
operator="inList"
value="admin" />
</authorization-rules>
这个例子中,operator
为设置成inList
,它将检查variable
中设置的session
变量。WAF知道如何检查包含所有基本列表对象的java.util.Collection
, java.util.Enumeration
和java.util.Map
的任何子类,因此,如果您将用户角色存储在这些子类中的任何一个中,WAF可以在其中搜索”value”属性所指定的值。
属性path
是必须的,它是一个正则表达式,它决定<must-match>
规则将应用于哪个路径。
属性variable
是必须的,告诉WAF在哪里搜索value
属性以授予访问权限
有五个地方可提供查找
属性operator
是必须的,告诉WAF对于在variable
属性中对value
值执行什么样的操作,共四个可选项
属性value
是必须的,表示需要通过测试的值。
<url-rules>
标签允许开发者在HTTP状态行(请求的第一行)数据执行检查,在该标签中,您可以根据请求的文件扩展名(restrict-extension),请求的HTTP方法(restrict-method)和是否通过SSL(enforce-https)限制访问。
<restrict-extension>
<restrict-extension>
标签允许开发者限制访问服务器上的某些文件后缀名。评估经常发现在服务器上找到未受保护的静态资源,如代码,库。
下面的示例展示了如何预防任何到生产服务器上JAVA源代码的请求
<url-rules>
<restrict-extension deny=".java" />
</url-rules>
属性deny
和allow
至少出现一个,且不能同时包含两个属性。但是可以有多个<restrict-extension>
标签来实现预期的效果。属性值可以是一个正则表达式,如:.*\<value here>$
<restrict-method>
默认情况下,大多数应用服务器允许用户滥用一些http方法,导致意外发生。<restrict-method>
标签允许开发者预防无用的http方法请求应用程序。
下面的示例中展示了<url-rules>
标签包含两个<restrict-method>
子标签:
<url-rules>
<restrict-method deny="GET" path=".*\.do$" />
<restrict-method allow="^(GET|POST|HEAD)$" />
</url-rules>
属性deny
和allow
至少出现一个,且不能同时包含两个属性。但是可以有多个<restrict-method>
标签来实现预期的效果,属性值可以是一个正则表达式。
白名单(allow属性)和黑名单(deny 属性)有利也有弊,根据实际情况,同时使用可能效果会更好。
属性path
是可选项,给WAF一个正则表达式来决定什么时候应用该规则,如果URL匹配path正则表达式,该规则即会执行。
<enforce-https>
条件允许的情况下,WEB应用应该使用SSL,如果应用使用相对链接,则不强制使用SSL,攻击者可能会诱骗受害者去点击一个没有使用SSL的链接,可能会导致用户暴露敏感信息。
为了防止这种事件的发生,<enforce-https>
规则强制使用SSL。下面的示例中展示了如何在整个站点中强制使用SSL,并配置了一些静态非敏感内容的例外情况,如果用户用非SSL请求了匹配的URL,将会通过302跳转到使用SSL的对应URL页面。
<url-rules>
<enforce-https path="/.*">
<path-exception>/index.html</path-exception>
<path-exception type="regex">/images/.*</path-exception>
<path-exception type="regex">/help/.*</path-exception>
</enforce-https>
</url-rules>
属性path
是必须的,决定了网站哪部分使用SSL。所有例外情况都应该在子标签<path-exception>
中列举出来。
子标签<path-exception>
是可选的,可以有多个标签表明例外路径,当type=regex
时,则支持正则匹配路径。
<header-rules>
标签允许开发者对http请求头数据执行检查,在该标签中,您可以使用基于userAgent(restrict-user-agent)或contentType(restrict-content-type)来限制访问。
<restrict-user-agent>
<restrict-user-agent>
标签允许开发者根据用户UA来限制对网站的访问,有些UA表示它即为公开的不需要的流量,比如搜索引擎的robots。
<header-rules>
<restrict-user-agent deny=".*GoogleBot.*" />
<restrict-user-agent allow=".*" />
</header-rules>
<restrict-content-type>
<restrict-content-type>
标签允许开发者根据请求内容类型限制对站点的访问。异常的content-types可以是CSRF攻击的指标,也可以用来绕过安全机制。
<header-rules>
<restrict-content-type deny=".*multipart.*" />
<restrict-content-type allow=".*" />
</header-rules>
<virtual-patchs>
允许开发者针对已知攻击实行虚拟补丁,如URL跳转,XSS,SQL注入等,您可以配置0个或多个<virtual-patch>
规则。
<virtual-patch>
<virtual-patch>
规则是WAF 策略文件中最重要的规则之一,许多利用自动化工具的攻击都可以通过虚拟补丁修复。在下面的示例中简单修复了XSS漏洞 :
<virtual-patch
id="scr-15520"
path="/foobar.jsp"
variable="request.parameters.q"
pattern="^[0-9a-zA-Z\s,\.]$"
message="detected exploit of SCR #15520" />
属性id
是<virtual-patch>
的唯一标识,如果使用了唯一的ID,则在日志中可以区分哪条规则被触发。
属性path
是应用到请求URI的正则表达式,若匹配则执行测试。
属性variable
告诉WAF在分析哪个位置的属性值,有两个值可选:
属性pattern
是一个正则表达式,如果匹配成功,则请求通过测试,若匹配失败,WAF会将它认为是严重的安全事件。
属性message
是<virtual-patch>
失败时要记录的文字字符串,日志会自动生成一些有价值的信息,这应该用来向人们指出这个规则失败的简单总结。