第二章 核心防御机制
防御机制的几个核心因素
- 处理用户访问应用程序的数据与功能,防止用户获得未授权访问
- 处理用户对应用程序功能的输入,防止错误输入造成不良行为
- 防范攻击者,确保应用程序在称为直接攻击目标是能够正常运转,并采取适当的防御与攻击措施挫败攻击者
- 管理应用程序本身,帮助管理者监控其行为,配置其功能
2.1 处理用户访问
2.1.1 身份验证
身份验证机制是应用程序处理用户访问的最基本机制。验证用户是指确定用户的真是身份。如果不采用这个机制,应用程序会将所有用户作为匿名用户对待,这是最低一级的信任。
实现机制
绝大多数web应用程序都采用传统的身份验证模型,即要求用户提交用户名与密码,再由应用程序对其进行核实,确认其合法性。在安全性至关重要的应用程序中,通常使用其他证书与多阶段登录过程强化这个基本模型。在安全性要求更高的情况下,可能需要基于客户端证书、智能卡、或质询-响应令牌使用其他身份验证模型。除核心登录过程外,身份验证机制往往还要采取一系列其他支持功能,如自我注册,账户回复和密码修改工具。
攻击点
常见问题是攻击者能够确定其他用户用户名,推测出他们的密码,或者利用其逻辑缺陷完全避开登录功能。
2.1.2 会话管理
处理用户访问的下一项逻辑任务是管理通过验证用户的会话,成功登陆应用程序后,用户会访问各种功能与页面。从浏览器提出一系列HTTP请求。于此同时,应用程序还会收到各类用户(包括通过验证的用户与匿名用户)发出的无数请求。为实施有效的访问控制,应用程序需要识别并处理每一名用户提交的各种请求。
实现机制
大多数web应用程序为每一位用户建立一个会话,并向用户发布一个标识会话的令牌,令牌本身是一组保存在服务器上的数据结构,用于追踪用户与应用程序的交互状态。令牌是一个唯一的字符串,应用程序将其映射到会话中。当用户收到一个令牌时,浏览器会在随后的HTTP请求中将它返回给服务器,帮助应用程序将请求与该用户联系起来。虽然许多应用程序使用隐藏表单字段或URL查询字符串传输会话令牌(seesion token),但HTTP cookie才是实现这一目的的常规方法。如果用户在一段时间内没有发出请求,会话将自动终止。
少数应用程序不向用户发布会话令牌,而是通过其它方法在多个请求中重复确认用户身份。如果使用HTTP内置的身份验证机制,那么浏览器会自动在每个请求中重复提交用户证书,帮助应用程序直接通过这些请求识别用户。在其他情况下,应用程序会将状态信息保存在客户端而非服务器上,通常还需要对这些信息进行加密,以防遭到破坏。
攻击点
会话管理机制的有效性取决于其令牌的安全性,绝大多数针对它的攻击都企图破坏其他用户的令牌,如果令牌被攻破,就可以伪装成被攻破的用户,像已经通过的验证用户一样使用应用程序。令牌生成过程中存在的缺陷是主要的漏洞来源,使攻击者能够推测出发布给其它用户的令牌;随后攻击者再利用令牌中的缺陷截获其它用户的令牌。
2.1.3 访问控制
处理用户访问的最后一个逻辑步骤是做出并实施正确的决策,决定允许或拒绝每一个请求。如果前面的机制运作正常,应用程序既可以从收到的每一个请求确认用户的身份。在此基础上,应用程序需要决定是否授权用户执行其所请求的操作或访问相关数据。
实现机制
一般需要实现某种精心设计的逻辑,并分别考虑各种相关应用程序领域与不同类型的功能。应用程序可支持无数不同的用户角色,每组角色都拥有特定的权限,每名用户只允许访问应用程序中的部分数据,应用程序可能需要根据用户的身份,通过特殊功能实现交易限制于其他检查。
攻击点
开发者经常会对用户与应用程序的交互方式作出错误假设,并常常会有所疏忽,在某些应用程序功能中省略访问控制检查。探查这些漏洞是一件费力的工作,因为需要对每一项功能重复进行相同的检查。
2.2 处理用户输入
所有用户输入都不可信。
2.2.1 输入的多样性
- URL
- 表单数据
- cookie
2.2.2 输入处理方法
- 拒绝已知的不良输入(黑名单)
- 接受已知的正常输入(白名单)
- 精华(删除恶意字符或“转义”)
- 安全数据处理(确保处理过程安全)
- 语法检查
2.2.3 边界确认
输入确认的任务就是净化到达的潜在恶意数据,然后将“洁净的”数据交给可信的应用程序。
存在的问题
- 难以在外部边界建立一个单独的机制,防御所有这些攻击
- 用户提交的一项输入可能会在不同的组件中引发许多操作,数据发生转换后,可能会变得与之前完全不同
- 防御不同类型的攻击可能需要对相互矛盾的用户输入执行各种确认检查
解决方法
应用程序在每一个信任边界上执行数据确认,在不同的处理阶段执行不同的确认检查
2.2.4 多步确认与规范化
存在的问题
- 对输入数据进行过滤时,无法递归过滤导致重新建立恶意表达式
- 编码转换过程中产生恶意表达式
解决方法
- 递归执行净化操作
- 使用web应用程序使用的标准编码方案
2.3 处理攻击者
2.3.1 处理错误
- 在生产环境下,应用程序不应在其响应中返回任何系统生产的消息或其它调试信息
- 使用try-catch块对错误进行处理
- 配置应用程序服务器,使其以自定义的方式处理无法处理的应用程序错误
- 使用日志记录错误
2.3.2 维护审计日志
日志应记录的事件
- 所有与身份验证功能有关的事件,如成功或失败的登录、密码修改
- 关键交易,如信用卡支付与转账
- 被访问控制机制阻止的访问企图
- 任何包含已知攻击字符串,公然表明恶意意图的请求
有效的审计日志功能一般会记录每个事件的发生时间、发出请求的IP地址和用户的账户。日志必须受到严格保护,避免未授权的读取或写入访问。
2.3.3 向管理员发出警报
警报监控的反常事件
- 应用反常
- 交易反常
- 包含已知攻击字符串的请求
- 请求中普通用户无法查看的数据被修改
2.3.4 应对攻击
应对攻击的手段
- 对攻击者提交的请求的相应越来越慢
- 终止攻击者的会话
- 要求其重新登录
- 要求其在继续攻击前执行其他步骤
2.4 管理应用程序
许多应用程序一般通过web界面在内部执行管理功能,在这种情况下,管理机制就成为应用程序的主要受攻击面。
- 身份验证机制中存在薄弱环节
- 没有对管理功能执行有效的访问控制
- 管理功能能够显示普通用户提交的数据,可被XSS利用
- 管理功能为进行可靠的安全性测试