中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java應用程序的安全沙箱機制是什么

發布時間:2022-01-17 09:48:02 來源:億速云 閱讀:130 作者:iii 欄目:數據安全

這篇“Java應用程序的安全沙箱機制是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java應用程序的安全沙箱機制是什么”文章吧。

如果你經常閱讀源碼,你會發現 Java 的源碼中到處都有類似于下面這一段代碼

class File {
  // 判斷一個磁盤文件是否存在
  public boolean exists() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
      security.checkRead(path);
    }
    ...
  }
}


這明顯是一個安全檢查代碼,檢查的是你是否有訪問磁盤路徑的權限,為什么 Java 語言需要這樣的安全檢查代碼呢?我們再看看客戶端套接字的 connect 函數源碼,它需要檢查用戶是否有connect 某個網絡地址的權限

class Socket {
  public void connect(SocketAddress endpoint, int timeout) {
    ...
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
       if (epoint.isUnresolved())
          security.checkConnect(epoint.getHostName(), port);
       else
          security.checkConnect(addr.getHostAddress(), port);
       }
    }
    ...
  }
}


再看服務端套接字的源碼,它會檢查端口的監聽權限

class ServerSocket {
  public void bind(SocketAddress endpoint, int backlog) {
    ...
    SecurityManager security = System.getSecurityManager();
    if (security != null)
       security.checkListen(epoint.getPort());
    ...
  }
}


似乎所有和 IO 操作有關的方法調用都需要進行安全檢查。跟 IO 操作相關的權限檢查似乎還可以理解,不是所有的 IO 資源用戶進程都是可以隨意訪問的。但是連環境變量都不讓隨意讀,而且限制的還不是所有環境變量,而是某個具體的環境變量,這安全檢查是不是有點過了?

class System {
  public static String getenv(String name) {
    SecurityManager sm = getSecurityManager();
    if (sm != null) {
       sm.checkPermission(new RuntimePermission("getenv."+name));
    }
    return ProcessEnvironment.getenv(name);
  }
}


這是因為 Java 的安全檢查管理器和操作系統的權限檢查不是一個概念,Java 編寫的不只是服務端應用程序,它還可以作為客戶端跑在瀏覽器上(Applet),它還可以以 app 的形式跑在手機上(J2ME),針對不同的平臺 JVM 會使用不同的安全策略。對于 Applet 而言,受限尤其嚴苛,通常都不允許 Applet 來操作本地文件。待 Java 的安全檢查通過后執行具體的 IO 操作時,操作系統還會繼續進行權限檢查。

我們平時在本地運行 java 程序時通常都不會默認打開安全檢查器,需要執行 jvm 參數才會打開

$ java -Djava.security.manager xxx
$ java -Djava.security.manager -DDjava.security.policy="${policypath}"


因為安全限制條件可以定制,所以還需要提供具體的安全策略文件路徑,默認的策略文件路徑是 JAVA_HOME/jre/lib/security/java.policy,下面讓我們來看看這個文件里都寫了些什么

// 內置擴展庫授權規則
// 表示 JAVA_HOME/jre/lib/ext/ 目錄下的類庫可以全權訪問任意資源
// 包含 javax.swing.*, javax.xml.*, javax.crypto.* 等等
grant codeBase "file:${{java.ext.dirs}}/*" {
 permission java.security.AllPermission;
};

// 其它類庫授權規則
grant {
 // 允許線程調用自己的 stop 方法自殺
 permission java.lang.RuntimePermission "stopThread";
 // 允許程序監聽 localhost 的隨機可用端口,不允許隨意訂制端口
 permission java.net.SocketPermission "localhost:0", "listen";
 // 限制獲取系統屬性,下面一系列的配置都是只允許讀部分內置屬性
 permission java.util.PropertyPermission "java.version", "read";
 permission java.util.PropertyPermission "java.vendor", "read";
 permission java.util.PropertyPermission "java.vendor.url", "read";
 permission java.util.PropertyPermission "java.class.version", "read";
 permission java.util.PropertyPermission "os.name", "read";
 permission java.util.PropertyPermission "os.version", "read";
 permission java.util.PropertyPermission "os.arch", "read";
 permission java.util.PropertyPermission "file.separator", "read";
 permission java.util.PropertyPermission "path.separator", "read";
 permission java.util.PropertyPermission "line.separator", "read";
 permission java.util.PropertyPermission "java.specification.version", "read";
 permission java.util.PropertyPermission "java.specification.vendor", "read";
 permission java.util.PropertyPermission "java.specification.name", "read";
 permission java.util.PropertyPermission "java.vm.specification.version", "read";
 permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
 permission java.util.PropertyPermission "java.vm.specification.name", "read";
 permission java.util.PropertyPermission "java.vm.version", "read";
 permission java.util.PropertyPermission "java.vm.vendor", "read";
 permission java.util.PropertyPermission "java.vm.name", "read";
};


grant 如果提供了 codeBase 參數就是針對具體的類庫來配置權限規則,如果沒有指定 codeBase 就是針對所有其它類庫配置的規則。

安全檢查沒有通過,那就會拋出 java.security.AccessControlException 異常。即使安全檢查通過了,操作系統的權限檢查仍然可能通不過,這時候又會拋出其它類型的異常。

授權規則采用白名單,依據上面的配置意味著啟用默認安全策略的 JVM 將無法訪問本地文件。如果需要訪問本地文件,可以增加下面的規則

permission java.io.FilePermission "/etc/passwd", "read";
permission java.io.FilePermission "/etc/shadow", "read,write";
permission java.io.FilePermission "/xyz", "read,write,delete";
// 允許讀所有文件
permission java.io.FilePermission "*", "read";


Permission 的配置參數正好對應了它的構造器參數

public FilePermission(String path, String actions) {
  super(path);
  init(getMask(actions));
}


Java 默認安全規則分為幾大模塊,每個模塊都有各自的配置參數

Java應用程序的安全沙箱機制是什么

其中 AllPermission 表示打開所有權限。還有一個不速之客 HibernatePermission,它并不是內置的權限模塊,它是 Hibernate 框架為自己訂制的,這意味著安全規則是支持自定義擴展的。擴展也很簡單,可以自己編寫一個 Permission 子類,實現它的 4 個抽象方法。

abstract class Permission {
  // 權限名稱,對于文件來說就是文件名,對于套接字來說就是套接字地址
  // 它的意義是子類可定制的
  private String name;
  // 當前權限對象是否隱含了 other 權限
  // 比如 AllPermission 的這個方法總是返回 true
  public abstract boolean implies(Permission other);
  // equals 和 hashcode 用于權限比較
  public abstract boolean equals(Object obj);
  public abstract int hashCode();
  // 權限選項 read,write,xxx
  public abstract String getActions();
}

class CustomPermission extends Permission {
  private String actions;
  CustomPermission(string name, string actions) {
    super(name)
    this.actions = actions;
  }
  ...
}


JVM 啟動時會將 profile 里面定義的權限規則加載到權限池中,用戶程序在特定的 API 方法里使用權限池來判斷是否包含調用這個 API 的權限,最終會落實到調用權限池中每一個權限對象的 implies 方法來判斷是否具備指定權限。

class CustomAPI {
  public void someMethod() {
    SecurityManager sec = System.getSecurityManager();
    if(sec != null) {
      sec.CheckPermission(new CustomPermission("xname", "xactions"));
    }
    ...
  }
}


啟用安全檢查,將會降低程序的執行效率,如果 profile 里面定義的權限規則特別多,那么檢查效率就會很慢,使用時注意安全檢查要省著點使用。

沙箱的安全檢查點非常多,下面列舉一些常見的場景

  1. 文件操作

  2. 套接字操作

  3. 線程和線程組

  4. 類加載器控制

  5. 反射控制

  6. 線程堆棧信息獲取

  7. 網絡代理控制

  8. Cookie 讀寫控制

如果你的服務端程序開啟了安全檢查,就需要在 policy 配置文件里打開很多安全設置,非常繁瑣,而且配置多了,檢查的性能也會產生一定損耗。這點有點類似 Android 的應用權限設置,在每個 Android 應用的配置文件里都需要羅列出一系列應用子權限。不過用 Java 來編寫服務端程序似乎開啟安全檢查沒有任何必要。

以上就是關于“Java應用程序的安全沙箱機制是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

故城县| 南乐县| 池州市| 盐津县| 吴江市| 古田县| 望都县| 壶关县| 灵武市| 神木县| 南安市| 泗阳县| 文山县| 宁晋县| 永安市| 贵阳市| 吐鲁番市| 肇州县| 菏泽市| 东城区| 北票市| 中江县| 沾益县| 北辰区| 安泽县| 枣强县| 永济市| 历史| 榆树市| 阿克苏市| 顺义区| 临颍县| 汾西县| 桑日县| 邛崃市| 莆田市| 长阳| 万州区| 盖州市| 萨迦县| 睢宁县|