程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 探索Java應用程序的安全需求

探索Java應用程序的安全需求

編輯:JAVA編程入門知識

  我們知道,維護應用程序的安全並不簡單。不過我們也清楚,完全可以采取一些措施來緩解安全缺陷帶來的風險。假如我們是網絡工程師,就可以將精力投入網絡分區和包過濾器方面的知識。假如用C語言編程,我們就保護程序以防止緩沖區溢出。 假如用Java編程,我們就考慮在安全治理器的保護之下運行應用程序。每種情況下,我們都用最佳實踐中獲得的知識來戰勝無意造成的系統故障。

  

  Java應用程序的安全條款,是本文所討論內容的依據。我們的討論把重點放在Java安全治理器方面,這是Java安全架構主題中的一個很小的子集。

  安全治理器是 java.lang.SecurityManager類或擴展自該類的一個類,且它在運行時檢查某些應用程序操作的權限。一旦受到安全治理器的控制,應用程序就只能執行那些由相關安全策略非凡准許的操作。默認情況下,該策略是在純文本 策略文件 中指定的。所涉及的操作包括:將文件寫入特定目錄、寫協同屬性、建立到特定主機的網絡連接,這裡列出的只是其中的一小部分。僅用一個簡單的JVM命令行選項即可迫使Java應用程序在一個安全治理器下運行,而且安全策略文件可以由任何文本編輯器輕松創建。

  雖然編輯這樣一個安全策略文件並添加各種相關規則並不難,不過獲得策略制訂權會更具有挑戰性。而且盡管沒人可以為我們提供這樣的策略制訂權,但工具能幫助我們理解那個策略應該是什麼。開發並使用這樣的工具是我們即將著手的工作。一旦我們有了它所發現的更寬泛、更細粒度的策略,就可以在開發產品運行時策略時將其作為起點,或者為了更好地理解和熟悉應用程序的安全需求而研究它。

  本文的核心代碼是一個通用的安全治理器,要使用它就需要有Sun的JSE 5 JVM。 為了從特定的Java系統類中獲得私有成員數據,從安全治理器對Java Reflecition API的依靠性中派生JSE 5(Java Standard Edition)的需求。由於缺乏對治理器運行所需的某有成員數據的公共訪問,因而需要使用Reflection API。使用私有成員反射的後果就是治理器與其運行所在的的JVM內部緊密相關。但這算不上什麼嚴重的後果,因為治理器是一個開發工具,而不是產品組件。一旦治理器提出一個策略制訂起點,我們就可以采用那個策略,並在任何現代JVM上運行遵從它的應用程序。

默認Java安全治理器

  現代文獻中所編寫、討論及引用的絕大多數Java代碼都代表著在不受安全治理器限制的情況下運行的應用程序。因而這種應用程序對所有的機器資源包括磁盤、網絡和應用程序關閉等有完全訪權限。不過這種寬泛的訪問權限很輕易受到限制。僅通過在JVM命令行上設置Djava.security.manager 選項,就可以迫使應用程序在默認的Java安全治理器下運行。

  看一下下面這個簡單的應用程序,其目的是讀取和打印用戶的主目錄

public class PrintHome {
   public static void main(String[] argv) {
      System.out.println(System.getProperty("user.home"));
   }
}

  編譯代碼,並讓它在默認安全治理器的限制下運行

$ cd $HOME/Projects/CustomSecurityManager
$ javac PrintHome.java
$ java -Djava.security.manager PrintHome
Exception in thread "main" java.security.AccessControlException: 
access denied (java.util.PropertyPermission user.home read)
...
at PrintHome.main(PrintHome.java:5)

  上面的應用程序中未能獲得並打印 user.home屬性,而且出於代碼可讀性方面的考慮,我們省略了棧跟蹤中的絕大部分。該應用程序未能執行是因為隨著缺省安全策略運行的缺省安全治理器禁止訪問user.home屬性。這個特權必須在運行策略文件中具體給出。

  創建一個包含單一規則的策略文件policy.txt

grant codeBase "file:/home/cid/Projects/CustomSecurityManager/"{
   permission java.util.PropertyPermission "user.home", "read";

  重新運行該應用程序,對策略文件的引用解決了對user.home的讀訪問問題

$ java -Djava.security.policy=policy.txt -Djava.security.manager PrintHome 
/home/cid

  注重到,我們通過設置系統屬性java.security.policy=policy.txt來將JVM引用到策略文件中。我們還假定PrintHome類位於/home/cid/Projects/CustomSecurityManager目錄中。policy.txt 文件中的規則答應任何包含在那個目錄中文件的代碼去讀取系統屬性user.home。結果,規則答應PrintHome像預期的那樣運行。包含代碼的文件就稱其為代碼庫。因此代碼庫就是一個類文件或jar文件

安全策略剖析工具:ProfilingSecurityManager

   <!-- frame contents --> <!-- /frame contents -->   正如我們前面提到的,創建一個安全策略文件並不難,即使像 策略池 這樣的實用工具可提供協助。而且在策略文件中答應有很強大的 語法快捷方式,它答應創建有表現力的、高效的規則。使用這種高級規則符號,我們可以指定,比如說,遞歸引用整個目錄樹的代碼庫URL。這種遞歸 URL 規范不僅非常有用、方便,而且能夠向代碼閱讀者屏蔽掉應用程序對資源需求的真實、細粒度的深度。這正是我們尋求的細節。

  

  因此我們的目標是雙方面的:首先,我們希望在安全策略的限制下運行應用程序,或者至少說,我們希望確定該應用程序的安全需求。其次,我們需要一種程序性的方法來確定那些需求。

  帶著這些目標,我們來介紹定制的安全治理器secmgr.ProfilingSecurityManager。這個類擴展了java.lang.SecurityManager,但未實施本文至此所討論的安全策略。不過,據說它會實施此類安全策略假如應用程序可以獲得在運行時訪問它所請求的一切內容的權利。那麼我們可接受這種說法,將其轉換成運行時安全策略的起點。這樣一來,我們的兩個目標就都可以實現。

  為了使用ProfilingSecurityManager,首先編譯並有策略地將其放在自己的jar文件中(源代碼可以在 資源 這一節找到)。單獨將ProfilingSecurityManager放到它自己的jar文件中將答應我們過濾並取消由一些源於它自己jar文件代碼庫的活動所產生的輸出規則。ProfilingSecurityManager通過以下代碼可以知道自己獨有的代碼庫,

if( url.toString().equals(thisCodeSourceURLString) ) {
   return null;
}

  從而可以避免自身報告。同時編譯該工具,並將其制成 jar:

$ mkdir -p classes lib
$ rm -rf classes/* lib/*
$ javac -d classes ProfilingSecurityManager.java
$ jar cf lib/psm.jar -C classes secmgr/manager
$ rm -rf classes/secmgr/manager

  在我們繼續講下去之前,應該講一下如何激活ProfilingSecurityManager ,使之成為應用程序安全治理器。回想前面,我們通過設置一個無對應屬性值的系統屬性Djava.security.manager來促使應用程序在缺省的Java安全治理器限制下運行。我們需要進一步推廣這種措施,並通過給系統屬性賦值將定制安全治理器指定為安全治理器:Djava.security.manager=secmgr.ProfingSecurityManager。因此被激活之後,ProfilingSecurityManager將寫入System.out,策略文件中需要的這些規則答應應用程序在無需拋出安全違反異常的情況下運行。然而,這些規則不能被處理成最終可用的形式,直到應用程序在ProfilingSecurityManager下完成其運行為止。為什麼呢?因為我們知道僅在那時應用程序才完成了以檢查資源為目的的請求訪問。所以為了使應用程序在ProfilingSecurityManager下完成運行時處理並整理這些規則,我們提供了一個簡單的Perl腳本parsecodebase.pl(見 示例代碼),以便以易於閱讀的格式聚集、格式化、輸出由代碼庫分類並組合的規則。

  好了,我們現在用指定為安全治理器的ProfilingSecurityManager 和由parsecodebase.pl處理的規則輸出來運行簡單的 PrintHome 程序,會產生如下結果:

$ java -cp .:lib/psm.jar -Djava.security.manager=secmgr.ProfilingSecurityManager
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved