站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题用mod_security保障Web Services的安全

用mod_security保障Web Services的安全

摘要: Web服务正在变为下一代web应用的一个完整部分。但是它也较容易被攻击。这些攻击的种类与传统的web应用所受到的攻击是相同的,但是形式上发生了变化。这些攻击会导致信息泄漏;另外,这些攻击有助于执行远程命令。通过使用WSDL,一个攻击者能够确定web服务的入口和可用的接口。这些接口或方法使用SOAP协议通过HTTP/HTTPS方式得到输入。如果在源代码层没有好的保护,您的应用就会处于危险。mod_security作为一个Apache web服务器模块,是一种保护web服务免受恶意攻击(包括封装在S
用mod_security保障Web Services的安全

Shreeraj Shah 06/09/2005

翻译 skater 08/31/2005


版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
英文原文地址:
http://www.onlamp.com/pub/a/onlamp/2005/06/09/wss_security.html
中文地址:
http://www.matrix.org.cn/resource/article/43/43728_mod_security.html
关键词: mod_security Web service


Web服务正在变为下一代web应用的一个完整部分。但是它也较容易被攻击。这些攻击的种类与传统的web应用所受到的攻击是相同的,但是形式上发生了变化。这些攻击会导致信息泄漏;另外,这些攻击有助于执行远程命令。通过使用WSDL,一个攻击者能够确定web服务的入口和可用的接口。这些接口或方法使用SOAP协议通过HTTP/HTTPS方式得到输入。如果在源代码层没有好的保护,您的应用就会处于危险。mod_security作为一个Apache web服务器模块,是一种保护web服务免受恶意攻击(包括封装在SOAP封套内的恶意数据)的理想解决方案。

问题域

Web服务所遭到的四种主要攻击:
•变量长度缓冲区(Variable-length buffer)注入
•元字符注入
•SQL注入
•SOAP错误代码信息暴露(译者注:是指返回的Exception信息的暴露)

通常防火墙配置会允许HTTP/HTTPS传输无碍的进入。通常对web服务的攻击会伪装成合法的HTTP/HTTPS传输,从而蒙骗了防火墙。这篇文章将告诉您如何区分合法的HTTP/HTTPS传输和恶意的HTTP/HTTPS传输,并截获恶意传输。这样将能够在很大程度上减轻对80/443端口的攻击。

解决方案是什么?

有很多解决方案,从安全代码到输入验证。一个途径是通过对每一个请求的内容用事先定义好的规则进行验证。这种途径在源代码层上阻止了恶意SOAP请求渗透入web服务。如您为web服务正确部署并配置了mod_security,它将能够阻止所有上述的攻击。这篇文章将详细的讨论mod_security如何能成为web 服务有效的防范工具。

当部署完web服务后,提供一个防御手段来防范不同类型的攻击是很重要的。每一种攻击都需要不同的防范策略。假设有这么一个银行—这个银行仅仅是一个作为例子的假想银行。

Blue 银行(www.bluebank.example.com)最近刚刚部署了web服务,并使用mod_security对web服务进行保护。该银行通过internet向它的金融合作伙伴和客户提供银行服务。它的web服务提供在线的客户服务,比如帐目结算,资金周转和更改用户信息。图1解释了在Blue Bank部署的web服务的架构。


图 1. Blue银行的部署

有许多部署web服务的方法。在这个例子中,web服务运行在Tomcat/Axis上。banking web服务应用以Java编码(以.jws作为扩展名)。
相关的Apache和Axis配置文件片断包含用来加载Tomcat的Apache httpd.conf:

LoadModule jk2_module modules/mod_jk2.so
JkSet config.file /usr/local/apache2/conf/workers2.properties


让web服务支持AxisServlet 的Axis web.xml文件:

                                            
AxisServlet
*.jws


像如上配置之后,您将可以在该服务器上部署任何web服务。如果您注意到该服务器发回的如下的头信息,您能够识别如下这一行:

Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4

以上的消息头说明服务器是运行于Tomcat模块mod_jk2/2.0.4之上的Apache/2.0.50 (Unix)。Axis作为Tomcat web应用的一部分并且已经可以部署web服务。为了给web服务层提供保护,Blue银行已经加载了有application级过滤能力的mod_security模块。下面一行在httpd.conf中的信息加载安全模块:

LoadModule security_module modules/mod_security.so

当部署好mod_security后,Blue银行可以在httpd.conf里添加过滤规则:

 
# Turn the filtering engine On or Off
SecFilterEngine On
SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On

. . .
# Other rules
. . .


通过上面的配置,Blue Bank已经为管理员和开发人员准备好创建web服务,并利用mod_security的有效的内容过滤能力来防范恶意HTTP/HTTPS请求。
考虑一个web服务例子
如:www.bluebank.example.com/axis/getBalance.jws.
这个web服务的WSDL请求来自:www.bluebank.example.com/axis/getBalance.jws?wsdl.
说明:www.bluebank.example.com是一个虚拟的域名,仅仅作为例子。

从WSDL得到 方法/接口 数据来显示帐目结算信息

仔细观察HTTP请求获得的WSDL应答结果。这里重点观察一个调用方法,该方法输入bank id 然后返回相关账目结算信息并通过Http传递给客户端。operation标签指定web服务能够调用的方法。相关的wsdl代码片断如下:




namespace="http://DefaultNamespace"
use="encoded"/>


namespace="http://www.bluebank.example.com/axis/getBalance.jws"
use="encoded"/>









如上面代码所示,当向该方法传入一个id将得到一个字符串类型的输出。当你向该方法传入一个account id,你将回得到该account id的账目结算。

通过HTTP方式调用web服务

Blue银行的客户或者合作伙伴可以通过向banking web服务发送正确格式的SOAP封套来得到要求的信息。图2展示了一个通过向服务发送account id 12123 来获取相应账目结算的HTTP请求。


图 2.通过HTTP方式调用web服务

有很多种方法来产生有正确格式的SOAP请求的SOAP客户。这里有一个用Perl SOAP::Lite实现的SOAP客户。下面的简单代码将生成一个SOAP请求。

#!perl -w
use SOAP::Lite;

print SOAP::Lite
-> service('http://www.bluebank.example.com/axis/getBalance.jws?wsdl')
-> getInput('12123');


在网络上探测到HTTP请求和应答是可能的,比如用ethereal。一个发送到www.bluebank.example.com 的包含id 信息为12123的HTTP/SOAP请求将产生如下信息:

POST /axis/getBalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 576
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

12123




...

HTTP/1.1 200 OK
Date: Mon, 03 Jan 2005 19:24:10 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Set-Cookie: JSESSIONID=69C6540CC427A8B064C0795ADDFC20EA; Path=/axis
Content-Type: text/xml;charset=utf-8
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://DefaultNamespace">
xsi:type="xsd:string">$2500




将Web服务与mod_security结合起来

Blue银行的web服务使用www.bluebank.example.com/axis/getBalance.jws的URL。为这个资源创建一套规则通常一个不错的主意。为达此目的,Blue银行将此资源通过以下方式加入到httpd.conf:


SecFilterEngine On
SecFilterDefaultAction "deny,log,status:500"
# Other rules
# ------- Rules for web services --------------------------

SecFilterInheritance Off
SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On

#---------------------------------------------------------------


下面的指令块为/axis/getBalance.jws应用了过滤标准。为了保护web服务它添加了必要的规则。这些规则在块中,如下:

# ------- Rules for web services --------------------------

SecFilterInheritance Off
SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On

#---------------------------------------------------------------


在这里有两个重要的指令:

SecFilterInheritance Off
这个指令关闭其他所有规则,为新的location建立一套规则创建一个干净的空间。(译者注:初始化,建立新空间)

SecFilterScanPOST On
由于web服务的方法调用是通过POST,所以这个指令是打开POST过滤器。
有了上面的配置,Blue Bank已经在mod_security中部署了一个“护盾”(译者注:防火墙)。该“护盾”也知道它的防护目标——客户端通过SOAP封套发送的id的内容。

防范攻击

作为防护所有恶意请求的第一步,Blue银行需要限制从客户端发送的id的值,防止传来无效值。SOAP请求用XML标签将id信息发送到web服务的代码中,像如下这样:


12123


为了过滤该请求,mod_security必须有一些途径去读取与标签相关的值(在这里标签是id);这个例子中的值是12123,mod_security提供一些途径限制通过POST请求发送的值。其中的一个方法就是使用自定义过滤器:


SecFilterInheritance Off
SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain


上面标示出来的行对请求中的id进行限制。POST_PAYLOAD截取POST数据块并与正则表达式(<\s*id[^>]*>)进行匹配。该正则表达式确保id标签存在,当存在的情况下才进行其余的检查。换句话说,如果id标签存在,mod_security继续下一个检查。

如果发送的POST请求中存在一个id,服务器能够执行信息。然而,一个恶意的客户端能够修改这个值加入恶意内容。有四种最流行的攻击方式。

攻击方式1:变量长度缓冲区注入(译者注:缓冲区溢出)

当把一个大的缓冲数据传给一个变量时可能会引起应用程序运行不正常或者在执行的时候“宕”掉的安全隐患。下面的规则将保护id变量免受此类攻击:


SecFilterInheritance Off
SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}""deny,status:500"


在上面的指令中,正则表达式<\s*id[^>]*>.{6,}限制缓冲变量的长度为5个字符。为了检查上面的代码块是否起作用,Blue银行可以发送两个请求,一个请求符合约束,另一个越界。

POST /axis/getBalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 576
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

12123




...

HTTP/1.1 200 OK
Date: Mon, 03 Jan 2005 19:24:10 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Set-Cookie: JSESSIONID=69C6540CC427A8B064C0795ADDFC20EA; Path=/axis
Content-Type: text/xml;charset=utf-8
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://DefaultNamespace">
xsi:type="xsd:string">$2500




在上面的例子中,将一个包含5个字符的缓冲数据传给web服务,服务收到后发回一个响应值为$2500。下面的例子将更改12123这个数据为121234,新的数据有6个字符,将得到一个新的响应信息,如下:

POST /axis/getBlalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 577
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

121234




...

HTTP/1.1 500 Internal Server Error
Date: Mon, 03 Jan 2005 22:00:33 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Content-Length: 657
Connection: close
Content-Type: text/html; charset=iso-8859-1

HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<head>
500 Internal Server Error
</head><body>

Internal Server Error


The server encountered an internal error or misconfiguration and was
unable to complete your request.


Please contact the server administrator, you@example.com and inform
them of the time the error occurred, and anything you might have done that
may have caused the error.


More information about this error may be available in the server
error
log.




Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d
mod_jk2/2.0.4
Server at 192.168.7.50 Port 80
</body>


mod_security模块拒绝了该请求。返回500状态。这说明请求根本没有到达web服务层。Blue 银行成功地防范了最常见和常常被忽略的缓冲区溢出攻击。(译者注:HTTP定义的500状态是服务器执行错误)

第二种攻击:元字符注入

另外一个主要的针对输入变量的威胁来自于使用像%,单引号(’),双引号(”)。这些字符会导致SQL注入攻击,并且可能会导致不必要的信息泄漏。采用下面的策略将保护web服务防范此类攻击。


SecFilterInheritance Off

SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On

SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}"
"deny,status:500"
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*"
"deny,status:500"


正则表达式<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*阻止不符合正则表达式的变量通过HTTP请求传入。这种转化字符集是mod_security的一项重要技术。
下面是传递一个id值为12'12的请求与应答:

POST /axis/getBalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 576
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

12'12




...

500 Internal Server Error
HTTP/1.1 500 Internal Server Error
Date: Mon, 03 Jan 2005 22:00:33 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Content-Length: 657
Connection: close
Content-Type: text/html; charset=iso-8859-1


如上,您可以看到返回500状态,说明这个攻击也失败了,mod_security捕获到了该攻击。

第三种攻击:SQL注入

在变量里注入SQL语句也是可能的。同时执行许多SQL语句也是可能的。如果您的应用的输入不“干净”,恶意的客户端将可以向已有的SQL请求增加额外的SQL语句,通常会导致严重的后果。


SecFilterInheritance Off
SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On

SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}"
"deny,status:500"
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*"
"deny,status:500"
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*select.+from[^<]*"
"deny,status:500"


被标示出来的正则表达式与“select * from . . .”子句匹配,如果匹配将会返回500状态。类似的您可以添加delete, update等正则表达式规则。mod_security会为您阻挡此类攻击。

第四种攻击:SOAP错误代码信息暴露

在web服务中有一种重要的信息是错误信息。一个错误的请求将会得到一段错误代码。下面是针对一个恶意用户故意非难Blue银行,向一个需要整型的变量发送字符类型“a”的请求时,Blue银行的应答结果。

POST /axis/getBalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 569
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">


a




...

500 Internal Server Error
HTTP/1.1 500 Internal Server Error
Date: Tue, 04 Jan 2005 16:22:14 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Set-Cookie: JSESSIONID=1CAF4CD0ED0F38FB40ECBC7BDAB56C75; Path=/axis
Content-Type: text/xml;charset=utf-8
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">


soapenv:Server.userException
java.lang.NumberFormatException:
For input string:"a"





如应答所示,错误的代码可能会暴露重要的内部信息,因此,非常有必要定义及使用过滤器。Blue Bank可以用下面的规则来过滤:

SecFilterInheritance Off

SecFilterDefaultAction "deny,log,status:500"
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On

SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}"
"deny,status:500"
SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*"
"deny,status:500"

SecFilterScanOutput On
SecFilterSelective OUTPUT "faultcode" "deny,status:500"


SecFilterScanOutput On
这个指令扫描一个输出数据块并使用过滤器

SecFilterSelective OUTPUT "faultcode" "deny,status:500"
这个指令块处理包含错误代码的传输。如果攻击者发送一个错误请求,比如上面的例子,它将会收到下面的响应:

HTTP/1.1 500 Internal Server Error
Date: Mon, 03 Jan 2005 22:00:33 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Content-Length: 657
Connection: close
Content-Type: text/html; charset=iso-8859-1

HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<head>
500 Internal Server Error
</head><body>

Internal Server Error


The server encountered an internal error or misconfiguration and was
unable to complete your request.


Please contact the server administrator, you@example.com and inform
them of the time the error occurred, and anything you might have done that
may have caused the error.


More information about this error may be available in the server
error
log.




Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d
mod_jk2/2.0.4
Server at 192.168.7.50 Port 80
</body>

如上,当正确配置了mod_security后,将可以阻止此类攻击。

总结

mod_security可能看起来只不过是安全世界里的又一个工具而已,但是它较现有的安全工具有自己独特的优势。在提供HTTP层防护的同时,mod_security支持POST_PAYLOAD过滤能力。
然而,mod_security的优势在于提供了允许开发人员和web管理员不需要修改源代码就可以来防护web服务的手段。它并不是使差代码变得可容忍;它通常意味着公司或者组织能够不需要运行冗长的代码就可以为它们的web服务装配附加的有效的安全保障。

这篇文章主要是讲述一种web服务安全技术,这种技术是一种有效的技术。您可以自由选择您自己的技术来保护web服务。

要了解更多关于mod_security的信息,请看Introducing mod_security, mod_security quick examples,和HOWTO: Enhancing Apache with mod_security。

Shreeraj Shah是Net-Square的创始人和主管。

↑返回目录
前一篇: 使用Eclipse RCP的IBM Workplace Managed Client
后一篇: 关于Apache Axis2的Web service消息