天天看點

《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對象的改變。