天天看点

《Java编码指南:编写安全可靠程序的75条建议》—— 指南3:为敏感可变类提供不可修改的包装器

本节书摘来异步社区《java编码指南:编写安全可靠程序的75条建议》一书中的第1章,第1.3节,作者:【美】fred long(弗雷德•朗), dhruv mohindra(德鲁•莫欣达), robert c.seacord(罗伯特 c.西科德), dean f.sutherland(迪恩 f.萨瑟兰), david svoboda(大卫•斯沃博达),更多章节内容可以访问云栖社区“异步社区”公众号查看。

字段的不变性可以防止其被意外修改以及恶意篡改,因此在接受输入或返回值时,防御性复制不可变字段是不必要的。然而,部分敏感类由于某些原因必须要被改变。幸运的是,可以通过不可修改的包装器,将可变类的只读访问权限授予不可信代码。例如,collection(集合)类包括一组包装器,允许客户端观察一个不可修改的集合对象视图。

在下面的违规代码示例中,mutable这个类允许内部数组对象被修改:

class mutableprotector extends mutable {

 @override

 public int[] getarray() {

  return super.getarray().clone();

 }

}

// ...<code>`</code>

private mutable mutable = new mutableprotector();

// may be safely invoked by untrusted caller having read ability

public mutable getmutable() {return mutable;}

在这个类中,调用getarray()方法不允许修改该类的私有内部状态,符合“obj05-j. defensively copy private mutable class members before returning their references”[long 2012]。然而,不可信的调用程序能调用setarray()方法修改mutable对象。

一般来说,通过对核心接口定义的所有方法(包括赋值方法),提供合适的包装器,可以将敏感类转化为安全视图(safe-view)对象。赋值方法的包装器必须抛出unsupportedoperationexception异常,这样调用者就不太可能做出影响属性不变性的操作。

在下面的解决方案中,setarray()方法覆盖了mutable.setarray()方法,防止了对mutable对象的改变。