1.2 注入攻击
当一个组件从超出该组件受信边界的外部数据源接收数据的时候,这些数据可能是恶意的,并且会导致注入攻击,如图1-1所示。
程序必须采取以下几个步骤,从而通过受信边界而收到的数据确保是适当的并且是没有恶意的。这些步骤包括:
验证(Validation):验证是指这样一个过程,该过程可以保证输入的数据处在预先设定好的有效的程序输入范围之内。这就要求这些输入符合类型和数值范围的要求,并且对各个类别和子系统来说,输入不会发生变化。
净化(Sanitization):在许多情况下,数据是从另一个受信域直接传递到组件当中来的。数据净化的过程是指,通过这个过程,可以确保数据符合接收该数据的子系统对数据的要求。数据净化也涉及如何确保数据符合安全性的要求,在这些要求中,需要考虑数据泄漏问题,或者需考虑在数据输出跨出受信边界的时候,敏感数据的暴露问题。净化可以通过消除不必要的字符输入来完成,比如对字符进行删除、更换、编码或转义操作。净化可能在数据输入(输入净化)之后或数据跨受信边界传输之前(输出净化)进行。数据净化和输入验证可能是并存的,并且是相互补充的。关于数据净化的详细情况说明,请参见规则IDS01-J。
标准化(Canonicalization)和归一化(Normalization):标准化的过程是指将输入最小损失地还原成等价的最简单的已知形式。归一化的过程是一个有损转换的过程,在这个过程中,输入数据会转化成用最简单的(可预期)形式来表现。标准化和归一化必须在数据验证之前进行,从而防止攻击者利用验证例程来除去不合法的字符,并由此构建一个不合法的(或者是有潜在恶意的)字符序列。关于这方面的更多信息,请参见规则IDS02-J。归一化应当在所有用户输入都收集完整之后进行。不要归一化那些不完整的数据,或者将经过归一化处理的数据和没有经过归一化处理的数据合并起来。
有一种情况需要特殊考虑,就是复杂的子系统接受代表特定操作命令或指令的字符串数据的问题。组件接受这些字符串数据的时候,在这些字符串数据中,可能包含的特殊字符会触发命令或动作,从而造成软件的安全漏洞。
以下是一些可以对命令进行解释或者对指令进行操作的组件的例子:
操作系统的命令解释器(见规则IDS07-J)
具备SQL兼容接口的数据库
XML解析器
XPath评估器
基于轻量级目录访问协议(Lightweight Directory Access Protocol, LDAP)的目录服务
脚本引擎
正则表达式(regex)编译器
在必须要把数据发送到处在另一个受信域的组件的时候,发送者必须确保数据经过适当的编码处理,从而在穿过受信边界的时候,满足数据接收者受信边界的要求。例如,尽管一个系统已经被恶意代码或数据渗透了,但如果系统的输出是经过适当转义和编码处理的,那么还是可以避免许多攻击的。