为什么要禁止除GET和POST之外的HTTP方法?使用不安全的HTTP方法可以看作是一个中危漏洞,换句话说,对于这些HTTP不安全方法,到底有多不安全呢?
一、HTTP请求方法有哪些
根据HTTP标准,HTTP请求可以使用多种方法,其功能描述如下所示:
HTTP1.0定义了三种请求方法:GET、POST、HEAD
HTTP1.1新增了五种请求方法:PUT、DELETE、CONNECT、OPTIONS、TRACE
二、不安全的请求方法会造成哪些攻击
其中许多请求方法可能对Web应用程序构成严重的安全风险,因为它们允许攻击者修改存储在Web服务器上的文件,删除服务器上的网页,并将WebShell上传到服务器,从而窃取合法用户的凭据。此外,在使用root权限的服务器时,必须禁用如下请求方法:
PUT:此方法允许客户端在Web服务器上上传新文件。由于PUT方法自身不带验证机制,攻击者可以利用PUT方法快捷简单地入侵服务器,上传Webshell或其他恶意文件(例如可以执行调用cmd.exe命令的ASP或PHP文件),从而获取敏感数据或服务器权限,或者将受害者的服务器用于存储自己的文件。
DELETE:此方法允许客户端删除Web服务器上的文件。攻击者可以非常简单直接的利用它来删除服务器上特定的资源文件,造成恶意攻击来破坏网站或发起拒绝服务(DOS)攻击。
CONNECT:此方法可以允许客户端使用Web服务器作为代理。
OPTIONS方法:将会造成服务器信息暴露,如中间件版本、支持的HTTP方法等。
TRACE:此方法只是将发送到服务器的任何字符串回显给客户端,主要目的是帮助开发人员调试程序。这种最初被认为是无害的方法被Jeremiah Grossman发现可用于发起一种称为跨站点跟踪(Cross Site Tracing)的攻击。
PATCH:RFC 5789标准定义的HTTP1.1方法,与PUT方法类似但非幂等,用来对已知资源进行局部更新,如果被请求修改的资源不存在,服务器可能会创建一个新的资源。此方法可被利用来修改资源的部分内容。
三、为什么要禁用HEAD请求方法
除了上面5种方法外,那有没有必要禁止HEAD请求方法呢?这是之前博主在渗透测试某网站后,向运维人员反馈漏洞时他们向我提出的问题,因为他们觉得HEAD方法和GET方法类似,而且还不返回具体相应内容,可见它比GET方法的权限还小,所以可以不禁用HEAD方法,但事实真得如此吗?
安全人员学习渗透测试时面对使用不安全的请求方法漏洞的时候都知道要禁用除了GET和POST之外的所有HTTP方法,但说实话博主之前并没有深入思考为什么要禁用HEAD请求方法,攻击者可能会使用什么姿势来利用HEAD请求方法进行攻击呢?下面举几个栗子说明一下:
很多网络环境使用基于请求的认证及访问控制策略(VBAAC),但是否会被绕过呢?我们来看下面这个JAVA EE web XML file的例子:
<security-constraint>
<web-resource-<a href="http://resources.infosecinstitute.com/collection/">collection</a>>
<url-pattern>/auth/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>root</role-name>
</auth-constraint>
</security-constraint>
这样的设定是告诉HTTP Servlet的Container,仅允许用户角色为root的使用者,通过GET和POST的请求,获取路径为/auth/*下的资源。乍一看,代码限定了用户访问权限,好像没什么问题。但是,我们却可以通过篡改HTTP请求来绕过限制!为什么?因为它并没有限制其他的HTTP请求应该被服务器拒绝!
我们可以用HEAD或者其他非GET/POST请求,诸如PUT,TRACK,TRACE,DELETE等,或者还可以尝试发送任意字符串(如ASDF),无比轻松的绕过这条规则,达到获取/auth/*路径下文件的目的。
我们总结一下可能会发生绕过的情形:
1. 允许非等幂的GET请求或者允许任意HTTP方法
2. 仅通过列出HTTP请求来控制安全
3. 不禁用没有列出的HTTP请求
如上所述,HEAD请求与GET类似,只不过服务器在响应时不会返回消息体。设想你的应用中有一段URL,若仅通过“拒绝GET和POST获取/auth路径下文件”这条规则保护,仍然是极不安全的。这里再举个栗子:
http://example.com/auth/root.jsp?cmd=adduser
如果你强制浏览器访问该URL,安全机制会被触发,检查请求资源和请求者是否符合授权规则。第一个当然就是检查并阻断浏览器发送的GET和POST请求了。这时,只要你使用 BurpSuite 等浏览器代理来拦截请求,并将拦截下来的GET请求替换成HEAD。由于HEAD未被列入安全约束规则中因此不会被阻止请求,最终adduser命令将被成功调用,并且由于 HEAD 功能,你的浏览器也将得到一个空消息体作为HEAD请求的响应。
表面上,允许使用HEAD方法并不是一个漏洞,因为RFC也有这种要求,但有时我们能利用它来绕过VBAAC。
如何防范HTTP Verb Tampering JAVA EE容器,让我们来看看如下安全约束策略:
<security-constraint>
<display-name>Example Security Constraint Policy</display-name>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/auth/security/*</url-pattern>
<!-- If you list http methods, only those methods are protected -->
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
</web-resource-collection>
...
</security-constraint>
以上代码中,伟大的程序猿列举并限制了POST,PUT,DELETE,GET等方法。因此只有当浏览器使用这些在<http-method>表中列举出的请求去获取/auth/security/*路径下文件时才会触发安全约束策略。
但是,把其他未列出的方法也一并禁用才是完善这条规则的最优解。比如由于HEAD并没有被列举出来,HEAD 请求将完全绕过此策略,之后应用服务器会将请求传递给 GET 处理程序。
确保JAVA EE安全性的正确打开方式是从安全约束策略中去除所有<http-method>,并使安全约束策略针对所有的HTTP请求方法。但如果仍想限制某些特定方法,建议参考如下方法,分2步创建安全约束策略。
<security-constraint>
<web-resource-collection>
<web-resource-name>site</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
...
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>site</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
...
</security-constraint>
如上,第1条策略将拒绝GET请求,而第2条策略则拒绝所有请求方法。
四、总结
建议把除了GET、POST的HTTP方法禁止有以下两方面原因:
1、除了GET、POST之外的其它HTTP方法,其刚性应用场景较少,且禁止它们的方法简单,实施成本低;
2、一旦让低权限用户可以访问这些方法,他们就能够以此向服务器实施有效攻击,威胁影响大。
安全人员进行渗透测试时,测试该漏洞方法可以通过使用OPTIONS方法遍历服务器使用的HTTP方法。但要注意的是,不同目录中激活的方法可能各不相同,而且许多时候,虽然OPTIONS反馈的某些方法有效,但实际上它们并不能使用,而许多时候即使OPTIONS请求返回的响应中没有列出某个方法,但该方法仍然可用。所以总的来说,建议手动测试每一个方法,确认其是否可用。
本站文章由渡缘人原创,如若转载请注明原文及出处:
https://www.hygrey.com/why-disable-unsafe-request-methods.html
Comments NOTHING