java安全編碼指南之基礎(chǔ)篇

      網(wǎng)友投稿 737 2025-03-31

      簡(jiǎn)介


      作為一個(gè)程序員,只是寫(xiě)出好用的代碼是不夠的,我們還需要考慮到程序的安全性。在這個(gè)不能跟陌生人說(shuō)話世界,扶老奶奶過(guò)馬路都是一件很困難的事情。那么對(duì)于程序員來(lái)說(shuō),尤其是對(duì)于開(kāi)發(fā)那種對(duì)外可以公開(kāi)訪問(wèn)的網(wǎng)站的程序員,要承受的壓力會(huì)大很多。

      任何人都可以訪問(wèn)我們的系統(tǒng),也就意味著如果我們的系統(tǒng)不夠健壯,或者有些漏洞,惡意攻擊者就會(huì)破門(mén)而入,將我們辛辛苦苦寫(xiě)的程序蹂躪的體無(wú)完膚。

      所以,安全很重要,今天本文將會(huì)探討一下java中的安全編碼指南。

      java平臺(tái)本身的安全性

      作為一個(gè)強(qiáng)類型語(yǔ)言,java平臺(tái)本身已經(jīng)盡可能的考慮到了安全性的,為我們屏蔽了大多數(shù)安全性的細(xì)節(jié)。

      比如可以為不同級(jí)別權(quán)限的代碼提供受限的執(zhí)行環(huán)境。 java程序是類型安全的,并且在運(yùn)行時(shí)提供了自動(dòng)內(nèi)存管理和數(shù)組邊界檢查,Java會(huì)盡可能的及早發(fā)現(xiàn)程序中的問(wèn)題,從而使Java程序具有很高的抵抗堆棧破壞的能力。

      盡管Java安全體系結(jié)構(gòu)在許多情況下可以幫助保護(hù)用戶和系統(tǒng)免受惡意代碼或行為不當(dāng)?shù)墓簦鼰o(wú)法防御可信任代碼中發(fā)生的錯(cuò)誤。也就說(shuō)如果是用戶本身代碼的漏洞,java安全體系是無(wú)法進(jìn)行判斷的。

      這些錯(cuò)誤可能會(huì)繞過(guò)java本身的安全體系結(jié)構(gòu)。在嚴(yán)重的情況下,可能會(huì)執(zhí)行本地程序或禁用Java安全性。從而會(huì)被用來(lái)從計(jì)算機(jī)和Intranet竊取機(jī)密數(shù)據(jù),濫用系統(tǒng)資源,阻止計(jì)算機(jī)的有用操作,協(xié)助進(jìn)一步的攻擊以及許多其他惡意活動(dòng)。

      所以,最大的安全在程序員本身,不管外部機(jī)制如何強(qiáng)大,如果核心的程序員出了問(wèn)題,那么一切都將歸于虛無(wú)。

      接下來(lái),我們看下java程序員應(yīng)該遵循一些什么行為準(zhǔn)則,來(lái)保證程序的安全性呢?

      安全第一,不要寫(xiě)聰明的代碼

      我們可能會(huì)在很多教科書(shū)甚至是JDK的源代碼中,看到很多讓人驚嘆的代碼寫(xiě)法,如果你真的真的明白你在做什么,那么這樣寫(xiě)沒(méi)什么問(wèn)題。但是很多情況下我們并不是很了解這樣寫(xiě)的原理,甚至不知道這樣寫(xiě)會(huì)出現(xiàn)什么樣的問(wèn)題。

      并且現(xiàn)代系統(tǒng)是一個(gè)多人協(xié)作的過(guò)程,如果你寫(xiě)了這樣的聰明代碼,很有可能別人看不懂,最后導(dǎo)致未知的系統(tǒng)問(wèn)題。

      給大家舉個(gè)例子:

      :(){:|:&};:

      上面是一個(gè)shell下面的fork炸彈,如果你在shell下面運(yùn)行上面的代碼,幾秒之后系統(tǒng)就會(huì)宕機(jī)或者運(yùn)行出錯(cuò)。

      怎么分析上面的代碼呢?我們把代碼展開(kāi):

      :()

      {

      :|:&

      };

      :

      還是不明白? 我們把:替換成函數(shù)名:

      fork()

      {

      fork|fork&

      };

      fork

      上面的代碼就是無(wú)限的fork進(jìn)程,通過(guò)幾何級(jí)數(shù)的增長(zhǎng),最后導(dǎo)致程序崩潰。

      java設(shè)計(jì)的很多大神把他們跳躍般的思想寫(xiě)到了JDK源代碼里面,大神們的思想經(jīng)過(guò)了千錘百煉,并且JDK是Java的核心,里面的代碼再優(yōu)化也不為過(guò)。

      但是現(xiàn)在硬件技術(shù)的發(fā)展,代碼級(jí)別的優(yōu)化可能作用已經(jīng)比較少了。為了避免出現(xiàn)不可知的安全問(wèn)題,還是建議大家編寫(xiě)一眼就能看出邏輯的代碼。雖然可能不是那么快,但是安全性有了保證。除非你真的知道你在做什么。

      在代碼設(shè)計(jì)之初就考慮安全性

      安全性應(yīng)該是一個(gè)在編寫(xiě)代碼過(guò)程中非常重要的標(biāo)準(zhǔn),我們?cè)谠O(shè)計(jì)代碼的時(shí)候就應(yīng)該考慮到相關(guān)的安全性問(wèn)題,否則后面重構(gòu)起來(lái)會(huì)非常費(fèi)事。

      舉個(gè)例子:

      public final class SensitiveClass {

      private final Behavior behavior;

      // Hide constructor.

      private SensitiveClass(Behavior behavior) {

      this.behavior = behavior;

      }

      // Guarded construction.

      public static SensitiveClass newSensitiveClass(Behavior behavior) {

      // ... validate any arguments ...

      // ... perform security checks ...

      return new SensitiveClass(behavior);

      }

      }

      上面的例子中我們使用了final關(guān)鍵字來(lái)防止我們的某些關(guān)鍵類被繼承擴(kuò)展。因?yàn)闆](méi)有擴(kuò)展性,所以安全性判斷會(huì)更加容易。

      同時(shí),java提供了SecurityManager和一系列的Permission類,通過(guò)合理的配置,我們可以有效的控制java程序的訪問(wèn)權(quán)限。

      避免重復(fù)的代碼

      和重復(fù)代碼相關(guān)的一個(gè)關(guān)鍵詞就是重構(gòu)。為什么會(huì)出現(xiàn)重復(fù)代碼呢?

      很簡(jiǎn)單,最開(kāi)始我們?cè)趯?shí)現(xiàn)一個(gè)功能的時(shí)候?qū)懥艘欢未a邏輯。結(jié)果后面還有一個(gè)方法要使用這段代碼邏輯。然后我們?yōu)榱藞D方便,就把代碼邏輯拷貝過(guò)去了。

      看起來(lái)問(wèn)題好像解決了。但是一旦這段業(yè)務(wù)邏輯要修改,那可就是非常麻煩的一件事情。因?yàn)槲覀冃枰业匠绦蛑兴谐霈F(xiàn)這段代碼的地方,然后一個(gè)一個(gè)的修改。

      為什么不把這段代碼提取出來(lái),做成一個(gè)單獨(dú)的方法來(lái)供其他的方法調(diào)用呢?這樣即使后面需要修改,也只用修改一處地方即可。

      在現(xiàn)實(shí)的工作中,我們經(jīng)常會(huì)遇到這種問(wèn)題,尤其是那種年久失修的代碼,大家都不敢修改,因?yàn)闋恳话l(fā)而動(dòng)全身。往往是修改了這邊忘記了那邊,最后導(dǎo)致bug重重。

      限制權(quán)限

      JDK專門(mén)提供了一個(gè)SecurityManager類,來(lái)顯示的對(duì)安全性進(jìn)行控制,我們看下SecurityManager是怎么使用的:

      SecurityManager security = System.getSecurityManager();

      if (security != null) {

      security.checkXXX(argument, ...);

      }

      SecurityManager提供了一系列的check方法,來(lái)對(duì)權(quán)限進(jìn)行控制。

      權(quán)限分為以下類別:文件、套接字、網(wǎng)絡(luò)、安全性、運(yùn)行時(shí)、屬性、AWT、反射和可序列化。管理各種權(quán)限類別的類是 :

      java.io.FilePermission、

      java.net.SocketPermission、

      java.net.NetPermission、

      java.security.SecurityPermission、

      java安全編碼指南之基礎(chǔ)篇

      java.lang.RuntimePermission、

      java.util.PropertyPermission、

      java.awt.AWTPermission、

      java.lang.reflect.ReflectPermission

      java.io.SerializablePermission

      JDK本身已經(jīng)使用了很多這些權(quán)限控制的代碼。比如說(shuō)我們最常用的File:

      public boolean canRead() {

      SecurityManager security = System.getSecurityManager();

      if (security != null) {

      security.checkRead(path);

      }

      if (isInvalid()) {

      return false;

      }

      return fs.checkAccess(this, FileSystem.ACCESS_READ);

      }

      上面是File類的canRead方法,我們會(huì)首先去判斷是否配置了SecurityManager,如果配置了,則去檢查是否可以read。

      如果我們?cè)趯?xiě)代碼中,遇到文件、套接字、網(wǎng)絡(luò)、安全性、運(yùn)行時(shí)、屬性、AWT、反射和可序列化相關(guān)的操作時(shí),也可以考慮使用SecurityManager來(lái)進(jìn)行細(xì)粒度的權(quán)限控制。

      構(gòu)建可信邊界

      什么是可信邊界呢?邊界主要起攔截作用,邊界里邊的我們可以信任,邊界外邊的我們就不能信任了。

      對(duì)于不能信任的外邊界請(qǐng)求,我們需要進(jìn)行足夠的安全訪問(wèn)控制。

      比如說(shuō)web客戶端來(lái)訪問(wèn)web服務(wù)器。web客戶端是在全球各地的,各種環(huán)境都有,并且是不可控的,所以web客戶端訪問(wèn)web服務(wù)器端的請(qǐng)求需要進(jìn)行額外的安全控制。

      而web服務(wù)器訪問(wèn)業(yè)務(wù)服務(wù)器又是不同的,因?yàn)閣eb服務(wù)器是我們自己控制的,所以安全程度相對(duì)較高,我們需要針對(duì)不同的可信邊界做不同的控制。

      封裝

      封裝(Encapsulation)是指一種將抽象性函式接口的實(shí)現(xiàn)細(xì)節(jié)部份包裝、隱藏起來(lái)的方法。

      封裝可以被認(rèn)為是一個(gè)保護(hù)屏障,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機(jī)訪問(wèn)。通過(guò)對(duì)接口進(jìn)行訪問(wèn)控制,可以嚴(yán)格的包含類中的數(shù)據(jù)和方法。

      并且封裝可以減少耦合,并且隱藏實(shí)現(xiàn)細(xì)節(jié)。

      寫(xiě)文檔

      最后一項(xiàng)也是非常非常重要的一項(xiàng)就是寫(xiě)文檔。為什么接別人的老項(xiàng)目那么痛苦,為什么讀源代碼那么困難。根本的原因就是沒(méi)有寫(xiě)文檔。

      如果不寫(xiě)文檔,可能你自己寫(xiě)的代碼過(guò)一段時(shí)間之后也不知道為什么當(dāng)時(shí)這樣寫(xiě)了。

      所以,寫(xiě)文檔很重要。

      載自:程序那些事

      Java 軟件開(kāi)發(fā)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:如何使用快捷鍵將特殊字符粘貼到Excel中?
      下一篇:【JavaScript入門(mén)-15】JavaScript中的DOM
      相關(guān)文章
      国产亚洲日韩在线三区| 无码一区二区三区亚洲人妻| 亚洲av午夜国产精品无码中文字| 亚洲福利视频网址| 婷婷亚洲久悠悠色悠在线播放| 国产美女亚洲精品久久久综合| 爱情岛论坛亚洲品质自拍视频网站| 亚洲欧洲av综合色无码| 亚洲国产精品久久久久秋霞小 | 久久亚洲国产精品一区二区| 亚洲综合AV在线在线播放| 中文亚洲成a人片在线观看| 亚洲偷自拍拍综合网| 2022中文字字幕久亚洲| 久久久久久A亚洲欧洲AV冫| 久久久久亚洲AV成人网人人网站 | 亚洲成aⅴ人片在线观| 亚洲最大免费视频网| 亚洲一级在线观看| 亚洲sss综合天堂久久久| 久久亚洲精品国产精品婷婷| 亚洲AV无码一区二区一二区| 国产精品亚洲精品日韩电影| 亚洲AV无码乱码在线观看| 亚洲裸男gv网站| 亚洲色欲色欲www在线丝| 亚洲国产精品一区二区久久hs | 久久久亚洲精华液精华液精华液 | 日产国产精品亚洲系列| 亚洲狠狠爱综合影院婷婷| 中文字幕亚洲第一| 亚洲国产精品福利片在线观看| 久久精品国产亚洲| 亚洲精品无码久久久久久久| 亚洲AV无码乱码在线观看代蜜桃 | 亚洲国产精品免费观看| 亚洲av无码偷拍在线观看| 亚洲国产av一区二区三区| 亚洲色欲久久久综合网东京热| 婷婷亚洲综合五月天小说| 亚洲国产精品白丝在线观看|