天天看点

《Java编码指南:编写安全可靠程序的75条建议》—— 指南10:不要使用clone()方法来复制不可信的方法参数

本节书摘来异步社区《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()方法复制不可信的参数会给攻击者执行任意代码的机会。