java安全编码指南之:敏感类的拷贝
文章目錄
- 簡(jiǎn)介
- 一個(gè)簡(jiǎn)單的SensitiveObject
- SensitiveObject的限制
- 對(duì)SensitiveObject的攻擊
- 解決辦法
簡(jiǎn)介
一般來說class中如果包含了私有的或者敏感的數(shù)據(jù)的時(shí)候是不允許被拷貝的。
如果一個(gè)class不想被拷貝,我們是不是不提供拷貝的方法就能保證class的安全了呢?
一起來看看吧。
一個(gè)簡(jiǎn)單的SensitiveObject
假如我們有下面的一個(gè)SensitiveObject,它的作用就是存儲(chǔ)一個(gè)password,并且提供了一個(gè)修改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));} }看上去沒什么問題,如果我們希望密碼被返回之后就不能夠被修改,應(yīng)該怎么做呢?
SensitiveObject的限制
為了實(shí)現(xiàn)上面的功能,我們可以考慮引入一個(gè)是否返回的變量,如果返回過了,就不允許進(jìn)行密碼修改了。
那么我們可以將上面的代碼修改成這樣:
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("已經(jīng)返回過了,無法重復(fù)返回");}}public final void doPasswordChange(){if(!returned) {for (int i = 0; i < password.length; i++) {password[i] = '*';}}} }通過加入了returned標(biāo)簽,我們可以控doPasswordChange方法,只能在未返回之前進(jìn)行密碼修改。
我們看下調(diào)用代碼:
SensitiveObject2 sensitiveObject2= new SensitiveObject2("www.flydean.com");sensitiveObject2.doPasswordEncrypt();System.out.println(sensitiveObject2.get());對(duì)SensitiveObject的攻擊
怎么對(duì)上述代碼進(jìn)行攻擊呢?
如果我們想在密碼返回之后仍然對(duì)密碼進(jìn)行修改,怎么做到呢?
如果SensitiveObject2可以拷貝,我們是不是就能夠保存一份char[]和boolean的副本了呢?
因?yàn)閏har[]屬于引用拷貝,所以在拷貝的副本里面對(duì)char[]進(jìn)行修改完全可以影響到原SensitiveObject2的內(nèi)容。
但是,雖然clone方法是定義在Object中的,如果子類沒有實(shí)現(xiàn)Cloneable接口的話,將會(huì)拋出CloneNotSupportedException異常。
考慮到SensitiveObject2不是一個(gè)final的類,我們可以通過繼承SensitiveObject2來實(shí)現(xiàn)目的:
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("www.flydean.com");MaliciousSubSensitiveObject object2 = object1.clone();String password1= object1.get();System.out.println(password1);object2.doPasswordChange();object1.printValue();} }可以看到,雖然object1先返回了password,但是這個(gè)password被clone過的object2進(jìn)行了修改,最終導(dǎo)致object1中的password值發(fā)生了變化。
解決辦法
怎么解決呢?
一個(gè)簡(jiǎn)單的方法就是將SensitiveObject class定義為final,這樣就不能繼承,從而避免了上訴問題。
本文的例子:
learn-java-base-9-to-20/tree/master/security
本文已收錄于 http://www.flydean.com/java-security-code-line-object-copy/
最通俗的解讀,最深刻的干貨,最簡(jiǎn)潔的教程,眾多你不知道的小技巧等你來發(fā)現(xiàn)!
歡迎關(guān)注我的公眾號(hào):「程序那些事」,懂技術(shù),更懂你!
總結(jié)
以上是生活随笔為你收集整理的java安全编码指南之:敏感类的拷贝的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java安全编码指南之:可见性和原子性
- 下一篇: java安全编码指南之:死锁dead l