java安全編碼指南之:敏感類的複製
簡介
一般來說class中如果包含了私有的或者敏感的資料的時候是不允許被複製的。
如果一個class不想被複製,我們是不是不提供複製的方法就能保證class的安全了呢?
一起來看看吧。
一個簡單的SensitiveObject
假如我們有下面的一個SensitiveObject,它的作用就是儲存一個password,並且提供了一個修改password的方法:
public class SensitiveObject1 {
private char[] password;
SensitiveObject1(String iniValue){ this.password = iniValue.toCharArray(); } public final String get() { return String.valueOf(password); } public final void doPasswordChange(){ for(int i = 0; i < password.length; i++) { password[i]= '*' ;} } public final void printValue(){ System.out.println(String.valueOf(password)); }
}
看上去沒什麼問題,如果我們希望密碼被返回之後就不能夠被修改,應該怎麼做呢?
SensitiveObject的限制
為了實現上面的功能,我們可以考慮引入一個是否返回的變數,如果返回過了,就不允許進行密碼修改了。
那麼我們可以將上面的程式碼修改成這樣:
public class SensitiveObject2 {
private char[] password;
private boolean returned=false;
SensitiveObject2(String iniValue){ this.password = iniValue.toCharArray(); } public final String get() { if(!returned) { returned=true; return String.valueOf(password); }else { throw new IllegalStateException("已經返回過了,無法重複返回"); } } public final void doPasswordChange(){ if(!returned) { for (int i = 0; i < password.length; i++) { password[i] = '*'; } } }
}
透過加入了returned標籤,我們可以控doPasswordChange方法,只能在未返回之前進行密碼修改。
我們看下呼叫程式碼:
SensitiveObject2 sensitiveObject2= new SensitiveObject2("); sensitiveObject2.doPasswordEncrypt(); System.out.println(sensitiveObject2.get());
對SensitiveObject的攻擊
怎麼對上述程式碼進行攻擊呢?
如果我們想在密碼返回之後仍然對密碼進行修改,怎麼做到呢?
如果SensitiveObject2可以複製,我們是不是就能夠儲存一份char[]和boolean的副本了呢?
因為char[]屬於引用複製,所以在複製的副本里面對char[]進行修改完全可以影響到原SensitiveObject2的內容。
但是,雖然clone方法是定義在Object中的,如果子類沒有實現Cloneable介面的話,將會丟擲CloneNotSupportedException異常。
考慮到SensitiveObject2不是一個final的類,我們可以透過繼承SensitiveObject2來實現目的:
public class MaliciousSubSensitiveObject extends SensitiveObject2 implements Cloneable{
MaliciousSubSensitiveObject(String iniValue) {
super(iniValue);
}
public MaliciousSubSensitiveObject clone(){ MaliciousSubSensitiveObject s = null; try { s = (MaliciousSubSensitiveObject)super.clone(); } catch(Exception e) { System.out.println("not cloneable"); } return s; } public static void main(String[] args) { MaliciousSubSensitiveObject object1 = new MaliciousSubSensitiveObject("); MaliciousSubSensitiveObject object2 = object1.clone(); String password1= object1.get(); System.out.println(password1); object2.doPasswordChange(); object1.printValue(); }
}
可以看到,雖然object1先返回了password,但是這個password被clone過的object2進行了修改,最終導致object1中的password值發生了變化。
解決辦法
怎麼解決呢?
一個簡單的方法就是將SensitiveObject class定義為final,這樣就不能繼承,從而避免了上訴問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69983372/viewspace-2724707/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- java安全編碼指南之:敏感類的拷貝Java
- java安全編碼指南之:方法編寫指南Java
- java安全編碼指南之:字串和編碼Java字串
- java安全編碼指南之:Number操作Java
- java安全編碼指南之:ThreadPool的使用Javathread
- java安全編碼指南之:基礎篇Java
- java安全編碼指南之:檔案IO操作Java
- java安全編碼指南之:序列化SerializationJava
- java安全編碼指南之:堆汙染Heap pollutionJava
- java安全編碼指南之:輸入校驗Java
- java安全編碼指南之:Mutability可變性Java
- java安全編碼指南之:輸入注入injectionJava
- java安全編碼指南之:異常處理Java
- java安全編碼指南之:執行緒安全規則Java執行緒
- java安全編碼指南之:鎖的雙重檢測Java
- java安全編碼指南之:宣告和初始化Java
- java安全編碼指南之:死鎖dead lockJava
- java安全編碼指南之:lock和同步的正確使用Java
- java安全編碼指南之:可見性和原子性Java
- java安全編碼指南之:Thread API呼叫規則JavathreadAPI
- java安全編碼指南之:檔案和共享目錄的安全性Java
- java工具類之編碼轉換工具類Java
- Python安全編碼指南Python
- Python 安全編碼指南Python
- Java安全編碼之使用者輸入Java
- 敏感詞 v0.19.0 新特性之敏感詞單個編輯,不必重複初始化
- Java安全之Unsafe類Java
- Java引用複製、淺複製、深複製Java
- 指南:不平衡分類的成本敏感決策樹(附程式碼&連結)
- [java IO流]之檔案複製Java
- Java物件複製之MapStruct使用Java物件Struct
- java進階(34)--File類、目錄複製Java
- Web前端安全之安全編碼原則Web前端
- java深度複製Java
- Java IO 流之拷貝(複製)檔案Java
- 體面編碼之JavaJava
- Orika - 類複製工具
- Java中物件的深複製和淺複製詳解Java物件