构建安全应用程序架构必须考虑的十二问
2016-02-20 19:45:13 来源: 赵长林 TechTarget中国 评论:0 点击:
应用程序的架构检查是指检查应用程序架构中当前的安全控制。这种检查有助于用户在早期确认潜在的安全漏洞,并在开始开发之前就极大地减少漏洞。糟糕的架构设计有可能暴露出应用程序的许多安全漏洞。最好的办法是在设计阶段就执行架构检查,因为在部署后再实施安全控制将花费高昂的成本和代价。
本文可作为架构师的安全设计指南,也可以为渗透测试人员执行应用程序架构检查提供参考,二者都可以将文中提及的方法和措施作为全局安全评估的一部分。
下图展示的是在设计阶段必须解决的一些主要问题。
在进行架构检查时,我们重点关注以下方面:应用程序架构的文档、部署和基础架构问题、输入验证、认证、授权、配置管理、会话管理、加密、参数操纵、例如管理、审计和记录、应用程序框架和库。
下面分别看一下这些方面:
1.应用程序架构的文档
我们应关注的第一个问题就是应用程序架构文档的实用性。每一个应用程序都应当有合适的可备查的架构图,其中要有对上述要点的深入解释,以及能够显示不同组件如何安装和保障安全的网络连接图。
2.对部署和基础架构的考虑
要检查应用程序赖以部署的基础架构,其中可能包括检查网络、系统、基础架构的性能监视等。
我们要考虑如下要点:
应用所要求的组件:支持此应用程序的操作系统是什么?硬件需求是什么?
防火墙实施的限制:要检查防火墙为应用程序定义的策略,要检查防火墙允许哪类通信,阻止哪类通信。
端口和服务要求:应用程序有可能还要与其它应用通信。要确认需要为该应用程序打开哪些端口和服务。
组件隔离:应用程序的不同组件应当相互隔离。例如,应用程序服务器和数据库服务器绝不应位于同一台机器中。
禁用明文协议:运行明文服务的端口应当关闭,并且不应该用于应用程序的任何部分。
3.输入验证
不健全的输入验证是导致应用程序安全问题的主要原因之一。适当的输入验证有助于防止跨站脚本攻击、SQL注入攻击等许多攻击。应对所有页面的每一个输入字段(包括隐藏的表单字段)实施验证。最佳实践是利用一种集中化的方法。
我们必须考虑如下要点:
验证用户输入的机制:要检查该应用是否能够验证用户输入或者能够处理所要求的输入。
绕过验证:我们要检查用户输入是如何被验证的。是否有可能绕过验证?要确认输入验证是否依赖应用程序的框架。要检查框架中是否有用户可以绕过验证的任何漏洞。
集中化的方法:如果企业使用定制方法来验证用户输入,就要检查是否采用集中化的方法。
在所有层中进行验证:作为一种最佳实践,我们应当在所有层上实施验证,也就是在业务层、数据层等层面上实施验证。
解决SQL注入问题:输入验证有助于在一定程度上减少SQL注入问题。我们应在后端利用参数化查询来检查应用程序是否可以应对SQL注入漏洞。
4.认证
认证是确认用户身份的活动。在应用程序中,验证是通过提供用户名和口令来实施的。不健全的认证机制可能导致绕过登录过程进而访问应用程序。这可能会带来重大损害。在设计应用程序时,应当实施强健的认证。
为有效地实施认证,我们必须考虑如下要点:
服务器端的认证控制:要确保在服务器端验证凭据而不是在客户端。客户端的认证很容易被绕过去。
认证的安全通道:程序在设计时,要确保通过加密通道来发送登录凭据。通过明文通道传送的凭据很容易被攻击者嗅探。
检查登录页是否可以通过HTTP协议传送。要检查在没有实施SSL证书的情况下,应用程序是否可以通过任何其它的端口访问。
强健的口令策略:企业的应用程序应当配置为只接受强口令。弱口令很容易遭受蛮力攻击。
认证cookie:要检查SSL是否在整个应用程序中实施,并且要检查任何页面的认证cookie是否通过明文传送。
服务账户:服务账户是一种服务应用程序赖以运行的账户。应用程序所要求的服务账户在与数据库通信时,应当有一套受限制的特权集。
框架的默认口令:许多应用程序框架都有一个默认的口令。要确保将口令改成一种不易猜测的强口令。
5.授权
授权决定了哪些资源可以被经认证的用户访问。不健全的授权控制可能导致特权提升攻击。企业应当考虑的要点如下:
特权提升和欺诈:在用户访问超过了其被允许访问的更多资源时,或者在用户能够执行超过其被允许的更多活动时,就发生了特权提升。要检查一下,如果用户要通过操纵请求或者通过直接访问未经授权的页面或资源,从而试图提升其特权,企业是否可以提供控制机制。
直接对象引用:要检查应用程序是否会根据用户提供的输入而提供了对于对象的直接访问。如果可以的话,攻击者就可以通过绕过授权而访问属于其它用户的资源。例如,下载其他用户的发票。
6.配置管理
企业应避免不健全的配置。在配置文件中存储的任何敏感信息都有可能被攻击者获得。
如下要点必须引起重视:
安全强化:要确保应用程序所要求的所有组件都是最新的,而且要安装最新的补丁。如果可能的话,要改变默认配置。
敏感数据:数据库连接字符串、加密密钥、管理员凭据或任何其它机密都不应当以明文形式存储。要检查配置文件是否可以防御非授权的访问。
长期cookie:我们应避免将敏感数据以明文形式长期存放在cookie中。用户可以看到和修改明文数据。要检查应用程序是否将明文数据长期存放在cookie中。
使用GET协议传递敏感数据:GET协议在查询串中发送数据。通过GET发送的敏感信息都可以通过浏览器历史或记录进行访问。
禁用不安全的方法:我们要验证应用程序只能接受GET和POST方法。TRACE、PUT、DELETE等其它方法都应当被禁用。
通过HTTP协议传输数据:在组件之间的通信,如在应用程序服务器和数据库服务器之间的通信都应当实施加密。
7.会话管理
会话是对用户活动的跟踪。强健的会话管理在应用程序的总体安全中扮演着一个重要角色。会话中的漏洞可能导致严重的攻击。
关于会话管理,如下要点应引起重视:
使用架构的默认会话管理:定制的会话管理可能存在多种漏洞。要确保不使用定制的会话管理器,并且使用应用程序框架的默认会话管理。
确保会话管理遵循如下最佳方法:会话ID应是随机的、长度足够长且保证唯一性;会话在登出后就失效;成功认证的会话ID和再次认证的会话ID应不同;会话 ID不应出现在URL中;在一段非活动时间过后,会话应超时;会话ID必须在安全通道中传送;要检查cookie的属性(HttpOnly、 Secure、path、domain等)的安全性;
8.加密
为保障存储数据的安全,或为保护在不安全的通道中数据传输的安全性,应用程序往往使用加密技术。
关于加密,我们应考虑如下要点:
定制加密不靠谱:设计一种专用的加密机制有可能导致更脆弱的保护。企业应使用由平台提供的安全加密服务。企业应检查应用程序中所使用的加密类型。
加密密钥管理:要检查是否存在加密密钥的管理策略,也就是说,是否有关于密钥的生成、分发、删除、消亡的策略。
保障加密密钥的安全:加密密钥用于作为一种加密或解密数据的输入。如果加密密钥遭到泄露,加密的数据就会遭到解密。
密钥的生命周期策略:在一段时间后,密钥应当重新生成。长期使用同样的密钥是不安全的安全实践。
9.参数操纵
借助参数操纵攻击,攻击者可以篡改从应用程序传输到Web服务器的数据。这会导致对服务的非授权访问。
因此,我们需考虑如下要点:
验证来自客户端的所有输入:在客户端实施验证可以减少服务器的负担,但仅依赖客户端的认证是一种不安全的实践。攻击者可以利用代理工具绕过客户端的认证。因而,我们应检查是否也在服务器上实施了认证。
不要依赖HTTP头:应用程序中的安全决策不应当是基于HTTP头的。如果应用程序仅通过检查“referrer”头来为网页服务,攻击者就可以通过改变代理服务器工具中的头部来绕过此控制。
加密cookies:cookies包含着由服务器授权给用户的数据。我们必须保护这类数据以防止非授权的操纵攻击。
ViewState中的敏感数据:例如,ASP.NET应用程序中的viewstate可能包含一些敏感数据,后者是用于在服务器上进行授权的根据。如果不启用消息认证码的话,viewstate中的数据就容易被篡改。因而,我们应检查是否使用了消息认证码来保护viewstate中的数据。
10.例外管理
不安全的例外处理机制可能暴露有价值的信息,攻击者可以利用这个缺陷来调整其攻击。如果没有例外管理,堆栈跟踪、框架细节、服务器细节、SQL查询、内部路径等敏感信息都有可能遭到泄露。我们必须检查是否部署了集中化的例外管理,要确保例外管理机制显示尽可能少的信息。
11.审计和日志
日志文件包含着事件的记录。这些事件可能是一次成功的或失败的登录尝试,或是数据的恢复、修改、删除等,或是网络通信等的任何企图。我们必须能够实时地监视日志。
因而,在构建应用程序的架构时必须重视如下要点:
支持和启用日志:必须检查是否支持应用程序和平台的日志功能。
记录事件:我们必须检查是否所有安全等级的重要事件都能够生成日志,如成功和失败的认证、数据访问、修改、网络访问等。日志应当包含事件的时间、用户身份、机器名和位置等。要确认记录哪些事件。
记录敏感数据:应用程序不应当包含日志的敏感数据,如用户凭据、口令哈希、信用卡细节等。
存储、安全、分析:日志文件应当存放在一个不同于应用程序正在运行的地方。日志文件应当复制并移动到一个永久性的存储器进行保留;必须保护日志文件,防止未经授权的访问、修改、删除等;必须定期地对日志文件进行分析。
12.应用程序框架和库
要确保应用程序框架和库的最新,并保证对其部署了相关的补丁。要确认在框架中没有使用默认的口令。还要检查是否使用了老的或易受攻击的框架。
结语
上述要点基本代表了设计安全的应用程序应关注的问题。在设计阶段实施这些要点可以减少为保障应用程序安全而花费的总成本。如果企业已经部署了应用程序,那么,应用程序架构的安全检查就成为全面安全评估的一个重要部分,并有助于修复已有的漏洞和改善未来的应用程序设计。
【编辑推荐】