《Java安全编码标准》一2.12 IDS11-J在验证前去掉非字符码点

2.12 IDS11-J在验证前去掉非字符码点

在早于Unicode 5.2的版本中,条款C7允许删除非字符码点。比如,在Unicode 5.1版本的C7条款中:
条款C7 当一个进程声称不会修改一个合法编码字符序列的意思时,它不应该改变该字符编码序列,除了有可能使用标准化字符编码来取代字符序列,或是删除非字符编码之外。
根据Unicode技术报告第36号的3.5节“删除非字符编码”,在考虑Unicode的安全的时候[Davis 2008b]:
不管一个字符是否被直接删除(不是替代),例如在C7的旧版本中提及的,将会导致安全问题。这个问题是这样的:一个网关可能会对所有的敏感字符串进行处理,比如“delete”。如果传递过来的是“delXlete”。这里“X”是非字符,网关会让它通过:序列“deXlete”可能通过并无害。然而,假设在通过网关之后,一个内部进程直接删除了X。这时,就形成了一个敏感的字符序列,并且会造成安全威胁。
修改任何一个字符串,包括对非字符数据的移除或者替代,必须在对该字符串进行验证之前进行。

2.12.1 不符合规则的代码示例

这个代码示例只接受合法的ASCII字符,并且它会删除所有的非ASCII码字符。同时,它也会检查是否存在

// "\uFEFF" is a non-character code point
String s = "<scr" + "\uFEFF" + "ipt>";?
s = Normalizer.normalize(s, Form.NFKC);
// Input validation
Pattern pattern = Pattern.compile("<script>");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
??System.out.println("Found black listed tag");
} else {
??// ...?
}

// Deletes all non-valid characters?
s = s.replaceAll("^\\p{ASCII}]", "");
// s now contains "<script>"

2.12.2 符合规则的方案

这个方案使用Unicode字符序列uFFFD来替代那些未知的或者不可表示的字符。同时,这样的替代是在其他净化之前完成的,比如对

String s = "<scr" + "\uFEFF" + "ipt>";

s = Normalizer.normalize(s, Form.NFKC);
// Replaces all non-valid characters with unicode U+FFFD
s = s.replaceAll("^\\p{ASCII}]", "\uFFFD");?

Pattern pattern = Pattern.compile("<script>");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
??System.out.println("Found blacklisted tag");
} else {
??// ...?
}

根据Unicode技术报告第36号, 考虑Unicode编码的安全问题 [Davis 2008b],“U+FFFD通常是没有问题的,因为它就是设计成这样使用的。也就是说,不管是在程序开发语言,还是在结构数据中,因为不会有任何语义上的含义,通常会在解析时出现错误。当输出字符集不是Unicode编码时,这个字符可能是不存在。”

2.12.3 风险评估

将非字符编码删除会允许恶意输入绕过验证检查。

2.12.4 相关规范

2.12.5 参考书目

时间: 2024-10-01 17:51:15

《Java安全编码标准》一2.12 IDS11-J在验证前去掉非字符码点的相关文章

《Java安全编码标准》一第 2 章 输入验证和数据净化(IDS)

第 2 章 输入验证和数据净化(IDS) 规 则 风险评估概要

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

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

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

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

《Java安全编码标准》一1.7 并发性、可见性和内存

1.7 并发性.可见性和内存 可以在不同线程之间共享的内存称为共享内存(shared memory)或内存堆(heap memory).本节使用变量(variable)这个名词来代表字段和数组元素[JLS2005].在不同的线程中共享的变量称为共享变量.所有的实例字段.静态字段以及数组元素作为共享变量存储在共享内存中.局部变量.形式方法参数以及异常例程参数是从来不能在线程之间共享的,不会受到内存模型的 影响. 在现代多处理器共享内存的架构下,每个处理器有一个或多个层次的缓存,会定期地与主存储器进

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

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

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

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

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

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

《Java安全编码标准》一1.3 敏感数据泄露

1.3 敏感数据泄露 系统的安全策略需要确定哪些信息是敏感的.敏感数据可能包括用户信息,比如社会保障或信用卡号码.密码或私钥.在不同等级受信域的组件中共享数据的时候,我们称这些数据是跨越受信边界的.因为在Java环境中,允许在同一个程序中的处在不同受信域的两个组件进行数据通信,从而会出现那些跨受信边界的数据传输.所以,如果在域中存在一个授权用户,而该用户没有数据接收权限,那么系统必须保证这些数据不会发送给处于该域的组件.如果有可能的话,这种处理只简单地禁止数据传输,也有可能对穿越受信边界的数据进

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

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