国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

java安全編碼指南之:對象構(gòu)建操作

瀏覽:4日期:2022-08-24 17:22:45

簡介

程序員肯定是不缺對象的,因?yàn)殡S時(shí)都可以構(gòu)建一個(gè),對象多了肯定會(huì)出現(xiàn)點(diǎn)安全問題,一起來看看在java的對象構(gòu)建中怎么保證對象的安全性吧。

構(gòu)造函數(shù)的異常

考慮下面的一個(gè)例子:

public class SensitiveOperation { public SensitiveOperation(){ if(!doSecurityCheck()){ throw new SecurityException('Security check failed!'); } } //Security check return false private boolean doSecurityCheck(){ return false; } public void storeMoney(){ System.out.println('Store 1000000 RMB!'); }}

上面的例子中,我們在構(gòu)造函數(shù)中做了一個(gè)securityCheck,因?yàn)檫@個(gè)securityCheck返回的值是false,所以會(huì)拋出SecurityException。

看下調(diào)用的例子:

public static void main(String[] args) { SensitiveOperation sensitiveOperation = new SensitiveOperation(); sensitiveOperation.storeMoney(); }

這個(gè)調(diào)用會(huì)拋出下面的異常:

Exception in thread 'main' java.lang.SecurityException: Security check failed! at com.flydean.SensitiveOperation.<init>(SensitiveOperation.java:11) at com.flydean.SensitiveUsage.main(SensitiveUsage.java:10)

那么問題來了,上面的這個(gè)class是不是安全的呢?

Finalizer Attack

上面的class不是final的,所以我們可以構(gòu)造一個(gè)class去繼承它。然后考慮這樣一個(gè)問題,當(dāng)構(gòu)造函數(shù)拋出異常之后,會(huì)執(zhí)行什么操作呢?

如果該對象已經(jīng)被構(gòu)建了,那么這個(gè)對象在GC的時(shí)候需要執(zhí)行finalize方法。那么我們是不是可以在finalize方法中繞過安全檢查呢?

看下面的例子:

public class SensitiveOperationFinalizer extends SensitiveOperation{ public SensitiveOperationFinalizer(){ } @Override protected void finalize() { System.out.println('We can still do store Money action!'); this.storeMoney(); System.exit(0); }}

上的例子中,我們繼承了SensitiveOperation,并且實(shí)現(xiàn)了finalize方法,在finalize中,我們調(diào)用了storeMoney。看下運(yùn)行的代碼:

public void testFinalizer() throws InterruptedException { try { SensitiveOperation sensitiveOperation = new SensitiveOperationFinalizer(); sensitiveOperation.storeMoney(); }catch (Exception e){ System.out.println(e.getMessage()); } System.gc(); Thread.sleep(10000); }

運(yùn)行結(jié)果:

Security check failed!We can still do store Money action!Store 1000000 RMB!

可以看到,雖然我們構(gòu)造函數(shù)拋出了異常,但是storeMoney的操作還是被執(zhí)行了!

這個(gè)操作就叫做Finalizer Attack。

解決Finalizer Attack

怎么解決這個(gè)構(gòu)造函數(shù)拋出異常的問題呢?這里給大家介紹幾種解決方法。

使用final class

如果使用final class,那么類是不能夠被繼承的,問題自然就解決了。

public final class SensitiveOperationFinal { public SensitiveOperationFinal(){ if(!doSecurityCheck()){ throw new SecurityException('Security check failed!'); } } //Security check return false private boolean doSecurityCheck(){ return false; } public void storeMoney(){ System.out.println('Store 1000000 RMB!'); }}

使用final finalize方法

因?yàn)樽宇愊胍貙慺inalize方法,如果我們的父類中finalize方法定義為final,也可以解決這個(gè)問題。

public final class SensitiveOperationFinal { public SensitiveOperationFinal(){ if(!doSecurityCheck()){ throw new SecurityException('Security check failed!'); } } //Security check return false private boolean doSecurityCheck(){ return false; } public void storeMoney(){ System.out.println('Store 1000000 RMB!'); } final protected void finalize() { }}

使用flag變量

我們可以在對象構(gòu)建完畢的時(shí)候設(shè)置一個(gè)flag變量,然后在每次安全操作的時(shí)候都去判斷一下這個(gè)flag變量,這樣也可以避免之前提到的問題:

public class SensitiveOperationFlag { private volatile boolean flag= false; public SensitiveOperationFlag(){ if(!doSecurityCheck()){ throw new SecurityException('Security check failed!'); } flag=true; } //Security check return false private boolean doSecurityCheck(){ return false; } public void storeMoney(){ if(!flag){ System.out.println('Object is not initiated yet!'); return; } System.out.println('Store 1000000 RMB!'); }}

注意,這里flag需要設(shè)置為volatile,只有這樣才能保證構(gòu)造函數(shù)在flag設(shè)置之前執(zhí)行。也就是說需要保證happens-before特性。

使用this或者super

在JDK6或者更高版本中,如果對象的構(gòu)造函數(shù)在java.lang.Object構(gòu)造函數(shù)退出之前引發(fā)異常,則JVM將不會(huì)執(zhí)行該對象的finalize方法。

因?yàn)镴ava確保java.lang.Object構(gòu)造函數(shù)在任何構(gòu)造函數(shù)的第一條語句之上或之前執(zhí)行。如果構(gòu)造函數(shù)中的第一個(gè)語句是對超類的構(gòu)造函數(shù)或同一個(gè)類中的另一個(gè)構(gòu)造函數(shù)的調(diào)用,則java.lang.Object構(gòu)造函數(shù)將在該調(diào)用中的某個(gè)位置執(zhí)行。否則,Java將在該構(gòu)造函數(shù)的代碼中的任何一個(gè)執(zhí)行之前執(zhí)行超類的默認(rèn)構(gòu)造函數(shù),并且將通過隱式調(diào)用執(zhí)行java.lang.Object構(gòu)造函數(shù)。

也就是說如果異常發(fā)生在構(gòu)造函數(shù)中的第一條this或者super中的時(shí)候,JVM將不會(huì)調(diào)用對象的finalize方法:

public class SensitiveOperationThis { public SensitiveOperationThis(){ this(doSecurityCheck()); } private SensitiveOperationThis(boolean secure) { } //Security check return false private static boolean doSecurityCheck(){ throw new SecurityException('Security check failed!'); } public void storeMoney(){ System.out.println('Store 1000000 RMB!'); }}

本文的例子:

learn-java-base-9-to-20/tree/master/security

以上這篇java安全編碼指南之:對象構(gòu)建操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 一级做a爰片久久毛片苍井优 | 99九九精品国产高清自在线 | 亚洲精品国产高清不卡在线 | 欧美日韩在线播放一区二区三区 | 草草久久97超级碰碰碰免费 | 亚洲免费专区 | 视频在线一区二区三区 | 国内国语一级毛片在线视频 | 国产成人精品一区二区免费 | 美国第一毛片 | 国产成人午夜片在线观看 | 精品国产综合区久久久久久 | 婷婷亚洲久悠悠色在线播放 | 国产人成午夜免费噼啪视频 | 欧美午夜在线 | 成人国产在线24小时播放视频 | 亚洲第一页在线视频 | 成年人免费在线视频观看 | 免费一级欧美毛片 | 亚洲天堂影院在线观看 | 成人中文字幕一区二区三区 | 欧美一级片网址 | 手机看片精品高清国产日韩 | 国产一级毛片一区二区三区 | 国产福利不卡一区二区三区 | 伊人久久大香线焦综合四虎 | 黄色大片三级 | 国产精品视频久久 | 欧美在线高清 | www.久草| 三级视频中文字幕 | 成 人 黄 色 视频播放16 | 久草草视频在线观看免费高清 | 91精品欧美成人 | 国产亚洲精品一区二区三区 | 亚洲一区二区三区四区 | 99国产精品欧美久久久久久影院 | 亚洲国产欧美在线不卡中文 | 黄页网址免费观看18网站 | 欧美黄a| 国产精品视频男人的天堂 |