沙箱安全機制的應用層面:360沙箱、win10沙箱、包括VMware Workstation、Oracle VM VirtualBox都可以充當沙箱去使用,沙箱中的操作與本機無關,進而保證本機的安全性
那什么是Java沙箱安全機制呢?
組成Java沙箱的基本組件
1.類加載體系結構(類的雙親委托機制)
2.class文件檢驗器
3.內置於Java虛擬機(及語言)的安全特性
4.安全管理器及Java API
Java安全模型的前三個部分——類加載體系結構、class文件檢驗器、Java虛擬機(及語言)的安全特性一起達到一個共同的目的:保持Java虛擬 機的實例和它正在運行的應用程序的內部完整性,使得它們不被下載的惡意代碼或有漏洞的代碼侵犯。
相反,這個安全模型的第四個組成部分是安全管理器,它主要 用於保護虛擬機的外部資源不被虛擬機內運行的惡意或有漏洞的代碼侵犯。這個安全管理器是一個單獨的對象,在運行的Java虛擬機中,它在對於外部資源的訪 問控制起中樞作用。
類加載體系結構
類加載器要加載一個類,它首先檢查此類是否已被加載,然后再委托雙親加載器加載此類,它的雙親加載器再委托它的雙親,這樣一直委托到啟動加載器,啟動加載 器在從核心API查找此類,如果有就返回此類,否則就他的子加載器就查找此類,如果都沒有就拋出ClassNotFound的異常。如下圖所示:
這種委托雙親的模式好處是:
1.啟動類加載器可以搶在標准擴展類裝載器之前去裝載類,而標准擴展類裝載器可以搶在類路徑加載器之前去裝載那個類,類路徑裝載 器又可以搶在自定義類加載器之前去加載它。所以Java虛擬機先從最可信的Java核心API查找類型,這是為了防止不可靠的類扮演被信任的類,試想一 下,網絡上有個名叫java.lang.Integer的類,它是某個黑客為了想混進java.lang包所起的名字,實際上里面含有惡意代碼,但是這種 伎倆在雙親模式加載體系結構下是行不通的,因為網絡類加載器在加載它的時候,它首先調用雙親類加載器,這樣一直向上委托,直到啟動類加載器,而啟動類加載 器在核心Java API里發現了這個名字的類,所以它就直接加載Java核心API的java.lang.Integer類,然后將這個類返回,所以自始自終網絡上的 java.lang.Integer的類是不會被加載的。
2.但是如果這個移動代碼不是去試圖替換一個被信任的類(就是前面說的那種情況),而是想在一個被信任的包中插入一個全新的類型,情況會怎樣呢?比如一個名為 java.lang.Virus的類,經過雙親委托模式,最終類裝載器試圖從網絡上下載這個類,因為網絡類裝載器的雙親們都沒有這個類(當然沒有了,因為 是病毒嘛)。假設成功下載了這個類,那你肯定會想,Virus和lang下的其他類痛在java.lang包下,暗示這個類是Java API的一部分,那么是不是也擁有修改Java.lang包中數據的權限呢?答案當然不是,因為要取得訪問和修改java.lang包中的權 限,java.lang.Virus和java.lang下其他類必須是屬於同一個運行時包的,什么是運行時包?運行時包是指由同一個類裝載器裝載的、屬 於同一個包的、多個類型的集合。考慮一下,java.lang.Virus和java.lang其他類是同一個類裝載器裝載的嗎?不是 的!java.lang.Virus是由網絡類裝載器裝載的!
class文件校驗器
通過四趟掃描,保證了class文件正確
第一趟是,檢查class文件的結構是否正確。比較典型的就是,檢查class文件是否以魔數OxCAFEBABE打頭(CA FE BA BE)。
通過這趟檢查,可以過濾掉大部分可能損壞的,或者壓根就不是class的文件,來冒充裝載。
第二趟是,檢查它是否符合java語言特性里的編譯規則。比如發現一個類的超類不是Object,就拋出異常。
第三趟是,檢查字節碼是否能被JVM安全的執行,而不會導致JVM崩潰。這里提到了一個停機的問題。內容是這樣的,“即不可能寫出一個程序,用它來判定作為其輸入而讀入的某個程序,是否會停機”。意思是,不可能寫一個程序,讓它告訴你,另外一個程序會不會中斷或崩潰。
第四趟是,符號引用驗證。一個類文件,它會包含它引用的其他類的全名和描述符,並跟他們建立符號引用(一種虛擬的,非物理連接的方式)。當程序第一次執行到需要符號引用的位置時,jvm會檢查這個符號鏈接的正確性,然后建立真正的物理引用(直接引用)。
內置於Java虛擬機(及語言)的安全特性
這些都是基礎的java語言特性,他們降低了java程序出現內存混亂,崩潰的幾率。
·結構化內存訪問(不使用指針,一定程度上讓黑客無法篡改內存數據)
·自動垃圾收集
·數組邊界檢查
·空引用檢查
·數據類型安全
安全管理器及Java API
這是安全沙箱中,離我們程序員最接近的一環。
1.securityMananger,是一個api級別的,可自定義的安全策略管理器,它深入到java api中,在各處都可以見到它的身影。比如SecurityClassLoader。默認情況下,java應用程序是不設置 securityManager 實例的(意味着不會起到安全檢查),這個實例需要我們在程序啟動時通過 System.setSecurityManager 來設置。
2.一般情況下,檢查權限是,通過 SecurityManager.checkPermission(Permission perm) 來完成的。外部程序通過,創建Permission實例,傳遞給前面的check。Permission是一個抽象類,需要繼承它實現不同的權限驗證,比如 FilePermission,代表對某個文件的讀寫權限。new FilePermission("test.txt", "read")