《Java安全编码标准》一1.2 注入攻击

1.2 注入攻击

当一个组件从超出该组件受信边界的外部数据源接收数据的时候,这些数据可能是恶意的,并且会导致注入攻击,如图1-1所示。

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

时间: 2024-08-03 15:53:01

《Java安全编码标准》一1.2 注入攻击的相关文章

《Java安全编码标准》一导读

前 言 在Java编程语言中,关键的安全编码要素是采用良好的文档和强制的编码规范.本书提供了在Java语言中的一系列安全编码规则.这些规则的目标是消除不安全的编码实践,因为这些不安全的因素会导致可利用的漏洞.如果应用这些安全编码标准,可以帮助设计出安全的.可靠的.健壮的.有弹性的.可用性和可维护性高的高质量系统,并且这些安全编码规范还可作为评估源代码质量特性的一个指标(不管使用的是手动的还是自动化的过程).对于使用Java编程语言开发的软件系统,这个编码规范具有广泛的影响. 目 录 第1章 概述

《Java安全编码标准》一2.1 IDS00-J净化穿越受信边界的非受信数据

2.1 IDS00-J净化穿越受信边界的非受信数据 许多程序会接受来自未经验证的用户数据.网络连接,以及其他来自于非受信域的不可信数据,然后它们会将这些数据(经过修改或不经修改)穿过受信边界送到另一个受信域中.通常,这些数据是以字符串的形式出现的,并且它们会有既定的内部数据结构,这种数据结构必须能够被子系统所解析.同时,必须净化这些数据,因为子系统可能并不具备处理恶意输入信息的能力,这些未经净化数据输入很有可能包含注入攻击. 值得注意的是,程序必须对传递给命令行解释器或者解析器的所有字符串数据进

《Java安全编码标准》一1.11 小结

1.11 小结 尽管作为一种相对安全的语言,Java语言及其类库还是在很大程度上存在着一些编程问题,从而造成系统安全漏洞.如果假设Java本身提供的功能特性可以减少一般的软件问题,并足够Java程序安全得不需要进行进一步检测,那么我们就大错特错了.因为任何在软件实现中出现的缺陷都会产生严重的安全影响,绷紧安全性这根弦是非常关键的,这样,当我们进行系统开发和部署时,就可以避免出现软件的安全漏洞问题.为了减少因为编程错误所带来的安全漏洞的可能性,Java开发人员应当遵循本编码标准中的安全编码规则,并

《Java安全编码标准》一2.4 IDS03-J不要记录未经净化的用户输入

2.4 IDS03-J不要记录未经净化的用户输入 当日志条目包含未经净化的用户输入时会引发记录注入漏洞.恶意用户会插入伪造的日志数据,从而让系统管理员以为是系统行为 [OWASP 2008].例如,用户在将冗长的日志记录拆分成两份时,日志中使用的回车和换行符可能会被误解.记录注入攻击可以通过对任何非受信的发送到日志的输入进行净化和验证来阻止.将未经净化的用户输入写入日志同样会导致向受信边界之外泄露敏感数据,或者在存储敏感数据的时候,违反了本地的安全规则.举例来说,如果一个用户要把一个未经加密的信

《Java安全编码标准》一2.8 IDS07-J不要向Runtime.exec()?方法传递非受信、未净化的数据

2.8 IDS07-J不要向Runtime.exec()?方法传递非受信.未净化的数据 外部程序通常被系统调用来完成某种需要的功能.这是一种重用的形式,也被认为是一种简单基于组件的软件工程方法.在应用没有净化非受信的输入并且在执行外部程序时使用这种数据,就会导致产生命令和参数注入漏洞. 每一个Java应用都有一个唯一的Runtime类的实例,通过它可以提供一个应用和应用运行环境的接口.当前的Runtime对象可以通过Runtime.getRuntime()方法获得.Runtime.getRunt

《Java安全编码标准》一1.5 拒绝服务

1.5 拒绝服务 拒绝服务攻击试图使计算机的资源不可获得,或者对需要使用该计算机资源的用户来说,会造成资源不足的情况.通常这种攻击是持续服务的服务器系统需要重点关注的,它与桌面应用程序有很大区别:然而,拒绝服务的问题可以出现在所有类别的应用上. 1.5.1 资源耗尽型的拒绝服务 拒绝服务可能出现在,相对于输入数据需要的资源消耗来说,使用比例上更为巨大的资源.通过客户端软件检查资源是否被过度消耗,并希望用户来处理与资源相关的问题是不合理的.但是,存在这样的客户端软件,它们可以检查那些可能会导致持久

《Java安全编码标准》一2.11 IDS10-J不要拆分两种数据结构中的字符串

2.11 IDS10-J不要拆分两种数据结构中的字符串 在历史遗留系统中,常常假设字符串中的每一个字符使用8位(一个字节,Java中的byte).而Java语言使用16位表示一个字符(Java中的Char类型).遗憾的是,不管是Java的byte类型还是char类型数据,都不能表示所有的Unicode字符.许多字符串使用例如UTF-8编码的方式存储和通信,而在这种编码中,字符长度是可变的. 当Java字符串以字符数组的方式存储时,它可以用一个字节数组来表示,字符串里的一个字符可以用两个连续的或更

《Java安全编码标准》一2.13 IDS12-J在不同的字符编码中无损转换字符串数据

2.13 IDS12-J在不同的字符编码中无损转换字符串数据 在String对象之间进行转换时,如果涉及不同的编码类型,可能会导致数据丢失. 根据Java API[API 2006] 对?String.getBytes(Charset)方法的描述: 该方法总会替代那些错误格式的输入和不可映射的字符序列,把它们替换成这些字符的字节数组. 当必须将一个String转化为字节数组时,例如写入一个文件,并且在这个字符串中含有不可映射的字符序列的时候,就必须进行正确的字符编码. 2.13.1 不符合规则的

《Java安全编码标准》一2.9 IDS08-J净化传递给正则表达式的非受信数据

2.9 IDS08-J净化传递给正则表达式的非受信数据 正则表达式在匹配文本字符串时被广泛使用.比如,在POSIX中,grep命令就支持正则表达式,使用它可以在指定文本中搜索模式.如果要了解正则表达式的基本情况,请参考Java教程[Tutorials 08].java.util.regex包提供了Pattern?类,这个类封装了一个编译过的正则表达式和一个Matcher类,通过Matcher类这个引擎,可以使用Pattern?在CharSequence中进行匹配操作.在Java中,必须注意不能误