本節書摘來異步社群《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()方法複制不可信的參數會給攻擊者執行任意代碼的機會。