就像无法通过明确的特征确定Web应用程序中存在的逻辑缺陷一样,同样也没有能够保护应用程序的万能防御措施。例如,虽然无法找到安全的方法替代危险的API,但是,下面的一系列最佳实践可显著降低在应用程序中出现逻辑缺陷造成的风险。
确保将应用程序各方面的设计信息清楚、详细地记录在文档中,以方便其他人了解设计者做出的每个假设。同时将所有这些假设明确记录在设计文档中。
要求所有源代码提供清楚的注释,包括以下信息:
每个代码组件的用途和预计用法;
每个组件对它无法直接控制的内容做出的假设;
利用组件的所有客户端代码引用,清楚记录它的效果有助于阻止在线注册功能中的逻辑缺陷。(注意:这里的“客户端”不是指客户端一服务器关系中的用户,而是指组件主要依赖的代码。)
在以安全为中心的应用程序设计审核中,考虑在设计过程中做出的每一个假设,并想象假设被违背的每种情况。尤其应注意任何应用程序用户可完全控制的假定条件。
在以安全为中心的代码审查中,从各个角度考虑以下两个因素:应用程序如何处理用户的反常行为和输入;不同代码组件与应用程序功能之间的相互依赖和互操作可能造成的不利影响。
我们可从本章描述的特殊逻辑缺陷实例中汲取以下教训。
始终记住,用户可以控制请求每一个方面的内容(请参阅第1章了解相关内容)。他们可
以按任何顺序访问多阶段功能;他们可以提交应用程序并未要求的参数;他们可以完全省略某些参数,而不仅仅是篡改参数值。
根据会话确定用户的身份与权限(请参阅第8章了解相关内容)。不要根据请求的任何其他特性对用户的权限做出任何假设。
当根据用户提交的数据或者用户执行的操作更新会话数据时,仔细考虑更新后的数据可能会给应用程序的其他功能造成什么影响。注意,这些数据可能会给由其他程序员或其他开发团队编写的完全无关的功能造成意想不到的不利影响。
如果一项搜索功能可用于查询禁止某些用户访问的敏感数据,确保那些用户无法利用该项功能、根据搜索结果推断出有用的信息。如果可以,根据不同的用户权限保留几个搜索索引(search index),或者使用当前用户的权限进行动态信息搜索。
如果一项功能允许用户从审计追踪中删除任何记录,在使用该项功能时应特别小心。另外,在大量使用审计的应用程序与双重授权模型中,考虑一名高级权限用户创建另一个相同权限的用户可能造成的影响。
如果应用程序根据数字交易限额执行检查,在处理用户输入前,必须对所有数据实施严格的规范化与数据确认。如果没有考虑到使用负数的情况,应立即拒绝包含负数的请求。
如果应用程序根据订购商品的数量决定折扣,必须保证在实际应用折扣前确定订单。
如果在将用户提交的数据提交给可能易于受到攻击的应用程序组件前,对其进行转义处理,一定要记得对转义字符本身进行转义,否则整个确认机制可能会遭到破坏。
始终使用适当的存储方法保存与某位用户有关的数据(或者保存在会话中,或者保存在用户资料中)。