本节书摘来异步社区《java编码指南:编写安全可靠程序的75条建议》一书中的第1章,第1.10节,作者:【美】fred long(弗雷德•朗), dhruv mohindra(德鲁•莫欣达), robert c.seacord(罗伯特 c.西科德), dean f.sutherland(迪恩 f.萨瑟兰), david svoboda(大卫•斯沃博达),更多章节内容可以访问云栖社区“异步社区”公众号查看。
创建可变方法参数的防御性副本,可以减轻来自各种安全漏洞的威胁,更多信息请参考《the cert® oracle® secure coding standard for java™》[long 2012]的“obj06-j. defensively copy mutable inputs and mutable internal components”。然而,对clone()方法不当地使用,可以使攻击者利用这一漏洞,提供看上去正常的参数,但随后返回意想不到的结果。这样的对象可能因此绕过验证和安全检查。当这样一个类可能会作为一个参数传递给一个方法时,应当把这个参数视为不可信任的,同时不要使用该类提供的clone()方法。另外,不要使用未经final修饰的类的clone()方法来创建防御性副本。
该指南是指南15的一个特定实例。
下面的违规代码示例定义了一个validatevalue()方法来验证时间值。
class maliciousdate extends java.util.date {
@override
public maliciousdate clone() {
// malicious code goes here
}
}<code>`</code>
然而,如果攻击者只能提供恶意的日期参数,但是没有足够特权,他还是可以绕过验证,从而混淆程序的其余部分。试想一下这个例子:
private void storedateindb(java.util.date date)
throws sqlexception {
final java.util.date copy = new java.util.date(date.gettime());
if (validatevalue(copy.gettime())) {
connection con =
drivermanager.getconnection(
"jdbc:microsoft:sqlserver://:1433",
"", ""
);
preparedstatement pstmt =
con.preparestatement("update accessdb set time = ?");
pstmt.setlong(1, copy.gettime());
// ...
下面的违规代码示例展示了一个java核心类atomicreferencearray的构造函数,它来自于java 1.7.0版本的第2次更新。
public atomicreferencearray(e[] array) {
// visibility guaranteed by final field guarantees
this.array = arrays.copyof(
array, array.length, object[].class);
使用clone()方法复制不可信的参数会给攻击者执行任意代码的机会。