Web 服务安全简介

Web 服务技术实现了应用程序之间的跨平台、跨编程语言通信,其最基本的组成部分为服务的提供者(Service Provider)和服务的请求者(Service Requester)。两者通过基于标准的 XML 格式的协议进行通信的,这种最常用的协议就是 SOAP(Simple Object Access Protocol)。按照 Web 服务的相关标准描述,服务的提供者应该首先通过 WSDL(Web Service Definition Language)和 UDDI(Universal Description, Discovery, and Integration)发布它所提供的服务到一个统一注册这些服务信息的存储库中去。这样,服务的请求者就可以通过 WSDL 和 UDDI 发现服务提供者提供的服务,并通过应用的调用方法来使用这个服务。

对于任何应用程序来说,保护信息访问的安全都是最基本的要求。在面向服务体系架构(Service Oriented Architecture,SOA)原则构造的复杂系统环境中,Web 服务扮演着各个系统组件之间的协调员的角色,因此 Web 服务的安全性尤为重要。Web 服务客观需要业界统一的安全规范体系,使各种系统能够以一个与平台和语言无关的方式安全地互相操作。

结合 Web 服务的技术特性,下文我们从传输层、消息层及应用层进行了解 Web 服务安全相关技术及特点。

传输层安全

目前绝大多数 Web 服务实现主要采用了基于 HTTP 的 SOAP 协议。HTTP 协议在安全性方面相当薄弱。HTTP 协议只提供一种身份确认的认证方法,它不提供数据隐私及数据完整性方面的保护。因此,对于基于 HTTP 的 Web 服务来说,我们应尽量采用安全套接字层(Secure Sockets Layer,SSL)来保障传输数据的安全。安全套接字层协议在客户机和服务器之间建立了一条安全的信息隧道,一个加密的 SSL 连接要求所有在客户机和服务器之间传输的信息都由发送软件加密,由接收软件解密,这样就提供了高度的机密性(数据隐私)。此外,所有在加密 SSL 连接上传输的数据都由一个自动数据完整性机制保护,确保数据在传输过程中未经更改。

这样,通过 SSL 我们能保障传输数据的认证、数据完整性及保密性。但 SSL 并不能解决所有的问题,SSL 仅仅保障数据传输过程中的数据安全,也不能解决消息层面所面临的安全问题。

消息层安全

2002 年 IBM 和 Microsoft 发布了一个联合的安全性白皮书“Security in a Web Services World:A Proposed Architecture and Roadmap”。它定义了一个全面的 Web 服务安全性模型,该模型对几个流行的安全性模型、机制和技术(同时包括对称密钥技术和公钥技术)加以支持、集成和统一,使各种系统能够以一个与平台和语言无关的方式安全地互相操作。它还描述了一组规范和方案,指出应怎样将这些规范一起使用。

Web 服务安全性 (WS-Security) 规范主要致力于提供消息层面的安全机制,在实现上主要在 SOAP 中通过 XML Signature、XML Encryption 和 Security Tokens(譬如 UsernameToken、X.509 Certificates、SAML 等)保障消息的安全性。Web 服务的安全性协议体系以 WS-Security 规范为基础,有六个主要的组成规范:

  • Web 服务策略 (WS-Policy) 和相关的规范,定义了关于服务交互方式的策略规则。
  • Web 服务信任 (WS-Trust),定义了安全交换的信任模型。
  • Web 服务隐私 (WS-Privacy),定义了如何维护信息的隐私。
  • Web 服务安全会话 (WS-Secure Conversation),定义了如何使用在 Web 服务策略 (WS-Policy)、Web 服务信任 (WS-Trust) 和 Web 服务隐私 (WS-Privacy) 中定义的规则,以在用于交换数据的服务之间建立安全会话。
  • Web 服务联盟 (WS-Federation),定义了分布式标识的规则以及如何对其进行管理。
  • Web 服务授权 (WS-Authorization),定义了如何处理对访问和交换数据的授权。

简而言之,WS-Security 通过消息完整性、消息机密性和消息认证及一些扩展模型保障了 SOAP 消息安全传递。但 WS-Security 并不能解决应用层面的安全问题。此外,Web 服务基于 XML 的特性还导致 Web 服务可能存在着 XML 相关的安全漏洞,譬如 XPath 注入、XML 解析相关的拒绝服务攻击(Denial of Service,DoS)等。

应用层层安全

很多人误以为 Web 服务没有界面,黑客就无法进行攻击。事实上,Web 服务通常仅是对现有应用层功能进行了封装,其后台应用层代码如果存在安全漏洞,黑客完全可以使用 Web 服务进行攻击这些漏洞。绝大多数情况下,Web 服务默认都支持 WSDL 的发布服务,黑客可以轻松获取 WSDL 从而了解 Web 服务提供的操作及 SOAP 消息格式,这使得攻击变得尤为简易。所以说,Web 应用中所面临的安全威胁同样存在于 Web 服务中。

因此,我们要走出误区,SSL 和 WS-Security 并不能解决所有的安全问题,SQL 注入、XSS 等 Web 层的常见安全漏洞同样可能存在于我们的 Web 服务中。Web 服务的安全不仅仅是传输层、消息层的安全,还要关注 Web 服务背后应用层代码中的安全漏洞。这需要开发团队从需求、编码、测试及部署等各个阶段进行预防、检测及修复,全面保障 Web 服务的安全。


Web 服务常见安全漏洞

前文介绍了 Web 服务安全相关基础技术,掌握以上知识不代表就能开发出安全的 Web 服务。俗话说“知己知彼,百战不殆”,作为应用开发 / 测试人员,我们除了掌握 Web 服务安全相关知识外,还应了解常见安全漏洞原理,这样才能够根据具体应用实际情况,因地制宜地进行安全建模、风险评估及安全测试等工作。

正如前文所分析的,Web 服务安全漏洞主要包括常见 Web 应用安全漏洞,以及 XML 相关的特殊安全漏洞。其中 Web 服务相关的应用层漏洞包括有命令注入(SQL、LDAP、OS Command)、缓冲区溢出、不正确的异常处理、无效的访问控制等。XML 相关的安全漏洞主要有命令注入(XPath、XQuery)、拒绝服务攻击(SOAP 数组溢出、递归的 XML 实体声明、超大消息体)以及信息泄漏(XML External Entity File Disclosure)等。鉴于篇幅所限,下文将选择其中最常见的几个漏洞进行剖析,以飨读者。

XPath 注入

SQL 注入是大家所熟知的安全漏洞,同样的原理,XPath 作为用来查询 XML 数据的语言,同样容易存在很多注入漏洞。某种程度来说,XPath 注入比 SQL 注入更简单,因为不同数据库产品的 SQL 语句有不同的方言,而 XPath 相对比较标准。我们假定某 Web 服务后台采用了这段代码来查询某 XML 数据文件中的记录。

清单 1. 存在注入漏洞的 XPath 查询

Stmt = "//users/user[username/text()='" + username+ "' and password/text()='" + password + "']/id/text()";

 

其中 username 和 password 是通过 SOAP 消息进行传输,如下文:

清单 2. 传递 XPath 查询参数的 SOAP 消息片段

<soap:Envelope xmlns:soap=""> <soap:Body> <fn:PerformFunction xmlns:fn=""> <fn:uid>testuser</fn:uid> <fn:password>testpassword</fn:password> </fn:PerformFunction> </soap:Body></soap:Envelope>

 

假如黑客利用 SOAP 传入 username="admin", password="' or '1'='1",以上 XPath 查询就变为:

清单 3. 遭注入的 XPath 查询

Stmt="//users/user[username/text()='admin' and password/text()='' or '1'='1']/id/text()";

 

这样黑客即可实现特权升级,访问到 admin 用户信息。

拒绝服务攻击

由于 Web 服务基于 XML 格式的协议进行通信(例如 SOAP 消息)。当 SOAP 消息到达 Web 服务器段时,服务器端会调用 XML Parser 解析 XML 数据(包括 DTD 声明),黑客可以利用大量的超大消息体或者递归的 XML 实体声明,让服务器端长时间解析 XML 数据,直至服务器资源耗竭,从而形成拒绝访问攻击,导致 Web 服务停止服务。

例如,SOAP 消息中可以加入以下大量无意义的实体声明,导致 SOAP 消息解析缓慢。

清单 4. SOAP 消息中无意义的实体声明示例

<!DOCTYPE root [<!ENTITY ha "Ha !"><!ENTITY ha2 "&ha; &ha;"><!ENTITY ha3 "&ha2; &ha2;">...<!ENTITY ha127 "&ha126; &ha126;"><!ENTITY ha128 "&ha127; &ha127;">]>

 

信息泄漏

某些 Web 服务会返回客户端指定的资源信息时,如果服务器端防范不当,则可能存在信息泄漏隐患。举个简单的类似 HelloWorld 的例子,假设某个 Web 服务会接受用户传来的名字“Jeremy”,然后返回“Hello, Jeremy!”。但,如果黑客传入如下参数:

清单 5. SOAP 消息中声明外部文件引用

<!DOCTYPE root [<!ENTITY myfile SYSTEM "file://c:/windows/win.ini">]>...<name>&myfile;</name>

 

服务器端如果疏于参数校验及文件访问权限控制,该 Web 服务可能返回系统文件的内容。


Web 服务安全推荐实践

显而易见,开发安全的 Web 服务是一项系统而复杂的工作。实际项目中 Web 服务的开发往往依赖于一些框架及中间件。因此如何开发安全的 Web 服务,需要结合各个框架和中间件进行具体分析。目前 DeveloperWorks 中有大量的资料,读者可自行研读,本文不再就此深入。下文笔者仅结合自己项目经历,就开发安全的 Web 服务所需要注意的一些事项,给大家共享一些实践经验,以供参考。

概而言之,开发安全的 Web 服务包括三个步骤:1、识别需要保护的 Web 服务资源;2、从传输层、消息层、应用层考虑安全设计;3、利用渗透测试检测安全漏洞并修复。

识别需要保护的 Web 服务资源

首先我们应评估需要保护的 Web 服务,了解它潜在的安全风险,整理其安全需求,作为后期的设计实现的基础。以下是笔者整理的检查清单,评估工作具体可以通过回答这些问题来进行整理。

  • 访问 Web 服务是否需要认证?
  • 是否需要检查服务请求者对 Web 服务的访问权限?
  • Web 服务是否接受请求者传递的参数?
  • 这些参数是否可行 & 如何校验?
  • Web 服务请求 / 响应的消息体是否包括敏感信息?
  • Web 服务的消息体如何传输 & 如何存储?
  • Web 服务的数据在传输 / 存储时是否需要加密处理?
  • Web 服务的后端程序是否跟其他第三方应用存在交互,这个过程是否可行?

利用以上这些评估工作的结果,最终形成 Web 服务的安全需求。

从三个层面进行综合安全设计

Web 服务设计开发过程中,需要将步骤一形成的安全需求落实到系统设计和编码实现中去。如果采用了基于 HTTP 的 SOAP 消息传输,我们推荐使用 SSL 保障传输层的安全。对于受保护的 Web 服务资源,建议通过 Security Token 保障消息的认证访问;对于敏感信息,建议使用 XML Encryption 进行加密;推荐使用 XML Signature 保障消息的完整性。具体编码过程中,需要遵循安全编程的原则,譬如参数的校验和转码、异常的封装处理等。推荐在开发阶段使用代码分析工具进行白盒安全检查。

利用渗透测试进行检测

Web 服务部署过程中,我们推荐使用 XML 网关(譬如 WebSphere DataPower Service Gateway)保障 XML 通信的安全。XML 网关通常处于外部网络与目标系统之间,解析接收到的 XML 信息流,并利用 XML Schema、WSDL 等判断 XML 消息是否符合要求,并根据检测及判断结果执行访问控制规则,将可信的合法信息流向目标系统,将非法信息进行阻截。因此,XML 网关有助于过滤 Web 服务所面临的 XML 相关的安全漏洞。

此外,系统部署阶段,我们推荐进行渗透测试,作为最后一道安全措施,进一步保障 Web 服务的安全性。IBM Rational AppScan Standard(下文简称为 AppScan)产品是业界领先的 Web 应用安全测试工具,它提供了集成的“通用服务客户机 (GSC)”,能基于 WSDL 探索 Web 服务,并结合测试策略库针对常见 Web 服务安全漏洞自动生成测试变体,自动执行这些测试变体并生成测试报告,从而实现自动化渗透测试。

Altoro Mutual 是 IBM 所提供的 Web 安全漏洞演示网站,下文笔者将向读者展示如何利用 AppScan 来检测该网站所存在的 Web 服务安全漏洞。考虑到 SoapUI 是大家熟悉的 Web 服务测试工具,本文将同时介绍如何结合 SoapUI 和 AppScan 进行检测 Web 服务安全漏洞。


利用 AppScan GSC 检测 Web 服务安全漏洞

  1. 选择“常规扫描”模板,新建扫描。

图 1. 新建常规扫描
图 1. 新建常规扫描
 

  1. 设置扫描类型为“Web Service 扫描”。

图 2. 设置 Web Service 扫描类型
图 2. 设置 Web Service 扫描类型
 

  1. 输入 WSDL 的访问地址:http://demo.testfire.net/transfer/transfer.asmx?wsdl

图 3. 设置 WSDL URL
图 3. 设置 WSDL URL
 

  1. 选择“Web Service”测试策略

图 4. 设置 Web Service 测试策略
图 4. 设置 Web Service 测试策略
 

  1. 点击“完成”,AppScan 将自动启动通用服务客户机 GSC。

图 5. 完成扫描配置向导
图 5. 完成扫描配置向导
 

  1. GSC 启动后,会自动根据提供的 WSDL 地址,导入 WSDL 文件,需要稍等片刻。

图 6. 常规服务客户端 GSC 自动导入 WSDL
图 6. 常规服务客户端 GSC 自动导入 WSDL
 

  1. 导入 WSDL 后,我们可以在左侧看到 Web 服务所提供的所有操作及对应的 SOAP 请求。

图 7. GSW 完成 WSDL 导入
图 7. GSW 完成 WSDL 导入
 

  1. 我们选择 TransferBalance 操作,点击其 ServiceSoap,右侧将出现请求 SOAP 消息的表单,选择“transDetails”,然后输入 transferDate,debitAccount,creditAccount 及 transferAmount 等参数,如下图所示,然后点击“调用”按钮。

图 8. 编辑 SOAP 请求数据
图 8. 编辑 SOAP 请求数据
 

  1. 等待并查看 Web 服务响应。

图 9. 查看 Web Service 响应
图 9. 查看 Web Service 响应
 

  1. 关闭 GSC,AppScan 会自动导入 GSC 探索到的 URL,我们可以在数据视图中查看该 URL 的请求及响应。

图 10. 查看 GSC 探索结果
图 10. 查看 GSC 探索结果
 

  1. 点击“扫描”-“仅测试”,AppScan 即自动对当前 Web 服务的 TransferBalance 操作进行自动化渗透测试。结果如下图所示。

图 11. 查看 Web Service 测试结果
图 11. 查看 Web Service 测试结果
 

请注意:

  • 以上案例,我们仅仅测试了 Web 服务中的其中一个操作,实际测试中应对所有的操作都进行测试;
  • 案例中,我们发现了 SQL 注入漏洞等常见 Web 应用漏洞,佐证了 Web 服务可能存在常见的 Web 应用安全漏洞;
  • 案例中我们使用了默认 Web Service 测试策略,默认 Web Service 测试策略不包括 XML 解析相关的拒绝服务测试变体,实际测试中应结合项目实际要求定制自己的测试策略。

利用 SoapUI 和 AppScan 检测 Web 服务安全漏洞

下面我们使用 SoapUI 重新探索上述案例,并使用 AppScan 扫描 SoapUI 探索的结果。如果没有安装 GSC,用户可以使用这种方案来检测 Web 服务的安全漏洞。

  1. 新建常规扫描,设置扫描类型为“Web 应用程序扫描”。

图 12. 新建 Web 应用扫描
图 12. 新建 Web 应用扫描
 

  1. 输入起始 URL:http://www.altoromutual.com/transfer/transfer.asmx?wsdl

图 13. 设置起始 URL
图 13. 设置起始 URL
 

  1. 登录方法选择“无”。

图 14. 设置登录方法
图 14. 设置登录方法
 

  1. 依旧选择“Web Service”测试策略。

图 15. 设置测试策略
图 15. 设置测试策略
 

  1. 因为我们将使用 SoapUI 进行探索,所以这里选择“稍后启动扫描”,然后点击“完成”按钮。

图 16. 完成向导并稍后启动扫描
图 16. 完成向导并稍后启动扫描
 

  1. 接下来,我们需要设置 SoapUI 和 AppScan 的代理关系。点击“工具”-“选项”,查看当前 AppScan 的动态代理端口。这里,我们将 AppScan 作为 Web 代理服务器,因此需要将此代理端口提供给 SoapUI。

图 17. 查看 AppScan 代理端口
图 17. 查看 AppScan 代理端口
 

  1. 打开 SoapUI,新建一个 SoapUI 工程,命名为“AltoroMutual”,WSDL 地址设为“http://www.altoromutual.com/transfer/transfer.asmx?wsdl”

图 18. 新建 soapUI 工程
图 18. 新建 soapUI 工程
 

  1. SoapUI 新建工程过程中,会自动导入 WSDL 定义。从下图可以看出,跟 GSC 类似,SoapUI 在左侧展示了 Web 服务的所有操作及其 SOAP 格式。

图 19. soapUI 工程创建完成
图 19. soapUI 工程创建完成
 

  1. 点击“File”-“Preferences”,进入 Proxy Settings,设置 AppScan 作为代理服务器,如下图所示。端口 2979 为步骤 6 中所查看到的端口号。点击“OK”保存设置。

图 20. 设置 soapUI 的代理
图 20. 设置 soapUI 的代理
 

  1. 双击“TransferBalance”下的 SOAP 请求,右侧会展示 SOAP 消息体,我们同样输入 transferDate,debitAccount,creditAccount 及 transferAmount 等参数,然后点击绿色三角按钮执行该 SOAP 请求。

图 21. 修改参数并提交 SOAP 请求
图 21. 修改参数并提交 SOAP 请求
 

  1. 稍等片刻,SoapUI 即展示出以上请求的响应信息。

图 22. 查看 Web Service 响应
图 22. 查看 Web Service 响应
 

  1. 关闭 SoapUI。AppScan 会自动弹出手工探测结果,提醒用户进行确认。直接点击“确定”。

图 23. 查看手工探索结果
图 23. 查看手工探索结果
 

  1. 同样进入 AppScan 数据视图,我们可以看到 AppScan 探索到了 SoapUI 所发出的 SOAP 请求及收到的响应。

图 24. AppScan 探索结果中的 SOAP 请求
图 24. AppScan 探索结果中的 SOAP 请求
 

  1. 点击“扫描”-“仅测试”,AppScan 即自动对当前探索结果进行自动化渗透测试。

以上两个案例的扫描脚本分别保存为“Demo_GSC.scan”、“Demo_SoapUI.scan”,供读者下载比较其配置方式的异同。