真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java應(yīng)用程序的安全沙箱機(jī)制是什么

這篇“Java應(yīng)用程序的安全沙箱機(jī)制是什么”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“Java應(yīng)用程序的安全沙箱機(jī)制是什么”文章吧。

創(chuàng)新互聯(lián)是專業(yè)的芒市網(wǎng)站建設(shè)公司,芒市接單;提供做網(wǎng)站、網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行芒市網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

如果你經(jīng)常閱讀源碼,你會(huì)發(fā)現(xiàn) Java 的源碼中到處都有類似于下面這一段代碼

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


這明顯是一個(gè)安全檢查代碼,檢查的是你是否有訪問(wèn)磁盤路徑的權(quán)限,為什么 Java 語(yǔ)言需要這樣的安全檢查代碼呢?我們?cè)倏纯纯蛻舳颂捉幼值?connect 函數(shù)源碼,它需要檢查用戶是否有connect 某個(gè)網(wǎng)絡(luò)地址的權(quán)限

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);
       }
    }
    ...
  }
}


再看服務(wù)端套接字的源碼,它會(huì)檢查端口的監(jiān)聽(tīng)權(quán)限

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


似乎所有和 IO 操作有關(guān)的方法調(diào)用都需要進(jìn)行安全檢查。跟 IO 操作相關(guān)的權(quán)限檢查似乎還可以理解,不是所有的 IO 資源用戶進(jìn)程都是可以隨意訪問(wèn)的。但是連環(huán)境變量都不讓隨意讀,而且限制的還不是所有環(huán)境變量,而是某個(gè)具體的環(huán)境變量,這安全檢查是不是有點(diǎn)過(guò)了?

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


這是因?yàn)?Java 的安全檢查管理器和操作系統(tǒng)的權(quán)限檢查不是一個(gè)概念,Java 編寫的不只是服務(wù)端應(yīng)用程序,它還可以作為客戶端跑在瀏覽器上(Applet),它還可以以 app 的形式跑在手機(jī)上(J2ME),針對(duì)不同的平臺(tái) JVM 會(huì)使用不同的安全策略。對(duì)于 Applet 而言,受限尤其嚴(yán)苛,通常都不允許 Applet 來(lái)操作本地文件。待 Java 的安全檢查通過(guò)后執(zhí)行具體的 IO 操作時(shí),操作系統(tǒng)還會(huì)繼續(xù)進(jìn)行權(quán)限檢查。

我們平時(shí)在本地運(yùn)行 java 程序時(shí)通常都不會(huì)默認(rèn)打開(kāi)安全檢查器,需要執(zhí)行 jvm 參數(shù)才會(huì)打開(kāi)

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


因?yàn)榘踩拗茥l件可以定制,所以還需要提供具體的安全策略文件路徑,默認(rèn)的策略文件路徑是 JAVA_HOME/jre/lib/security/java.policy,下面讓我們來(lái)看看這個(gè)文件里都寫了些什么

// 內(nèi)置擴(kuò)展庫(kù)授權(quán)規(guī)則
// 表示 JAVA_HOME/jre/lib/ext/ 目錄下的類庫(kù)可以全權(quán)訪問(wèn)任意資源
// 包含 javax.swing.*, javax.xml.*, javax.crypto.* 等等
grant codeBase "file:${{java.ext.dirs}}/*" {
 permission java.security.AllPermission;
};

// 其它類庫(kù)授權(quán)規(guī)則
grant {
 // 允許線程調(diào)用自己的 stop 方法自殺
 permission java.lang.RuntimePermission "stopThread";
 // 允許程序監(jiān)聽(tīng) localhost 的隨機(jī)可用端口,不允許隨意訂制端口
 permission java.net.SocketPermission "localhost:0", "listen";
 // 限制獲取系統(tǒng)屬性,下面一系列的配置都是只允許讀部分內(nèi)置屬性
 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 參數(shù)就是針對(duì)具體的類庫(kù)來(lái)配置權(quán)限規(guī)則,如果沒(méi)有指定 codeBase 就是針對(duì)所有其它類庫(kù)配置的規(guī)則。

安全檢查沒(méi)有通過(guò),那就會(huì)拋出 java.security.AccessControlException 異常。即使安全檢查通過(guò)了,操作系統(tǒng)的權(quán)限檢查仍然可能通不過(guò),這時(shí)候又會(huì)拋出其它類型的異常。

授權(quán)規(guī)則采用白名單,依據(jù)上面的配置意味著啟用默認(rèn)安全策略的 JVM 將無(wú)法訪問(wèn)本地文件。如果需要訪問(wèn)本地文件,可以增加下面的規(guī)則

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 的配置參數(shù)正好對(duì)應(yīng)了它的構(gòu)造器參數(shù)

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


Java 默認(rèn)安全規(guī)則分為幾大模塊,每個(gè)模塊都有各自的配置參數(shù)

Java應(yīng)用程序的安全沙箱機(jī)制是什么

其中 AllPermission 表示打開(kāi)所有權(quán)限。還有一個(gè)不速之客 HibernatePermission,它并不是內(nèi)置的權(quán)限模塊,它是 Hibernate 框架為自己訂制的,這意味著安全規(guī)則是支持自定義擴(kuò)展的。擴(kuò)展也很簡(jiǎn)單,可以自己編寫一個(gè) Permission 子類,實(shí)現(xiàn)它的 4 個(gè)抽象方法。

abstract class Permission {
  // 權(quán)限名稱,對(duì)于文件來(lái)說(shuō)就是文件名,對(duì)于套接字來(lái)說(shuō)就是套接字地址
  // 它的意義是子類可定制的
  private String name;
  // 當(dāng)前權(quán)限對(duì)象是否隱含了 other 權(quán)限
  // 比如 AllPermission 的這個(gè)方法總是返回 true
  public abstract boolean implies(Permission other);
  // equals 和 hashcode 用于權(quán)限比較
  public abstract boolean equals(Object obj);
  public abstract int hashCode();
  // 權(quán)限選項(xiàng) 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 啟動(dòng)時(shí)會(huì)將 profile 里面定義的權(quán)限規(guī)則加載到權(quán)限池中,用戶程序在特定的 API 方法里使用權(quán)限池來(lái)判斷是否包含調(diào)用這個(gè) API 的權(quán)限,最終會(huì)落實(shí)到調(diào)用權(quán)限池中每一個(gè)權(quán)限對(duì)象的 implies 方法來(lái)判斷是否具備指定權(quán)限。

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


啟用安全檢查,將會(huì)降低程序的執(zhí)行效率,如果 profile 里面定義的權(quán)限規(guī)則特別多,那么檢查效率就會(huì)很慢,使用時(shí)注意安全檢查要省著點(diǎn)使用。

沙箱的安全檢查點(diǎn)非常多,下面列舉一些常見(jiàn)的場(chǎng)景

  1. 文件操作

  2. 套接字操作

  3. 線程和線程組

  4. 類加載器控制

  5. 反射控制

  6. 線程堆棧信息獲取

  7. 網(wǎng)絡(luò)代理控制

  8. Cookie 讀寫控制

如果你的服務(wù)端程序開(kāi)啟了安全檢查,就需要在 policy 配置文件里打開(kāi)很多安全設(shè)置,非常繁瑣,而且配置多了,檢查的性能也會(huì)產(chǎn)生一定損耗。這點(diǎn)有點(diǎn)類似 Android 的應(yīng)用權(quán)限設(shè)置,在每個(gè) Android 應(yīng)用的配置文件里都需要羅列出一系列應(yīng)用子權(quán)限。不過(guò)用 Java 來(lái)編寫服務(wù)端程序似乎開(kāi)啟安全檢查沒(méi)有任何必要。

以上就是關(guān)于“Java應(yīng)用程序的安全沙箱機(jī)制是什么”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


當(dāng)前文章:Java應(yīng)用程序的安全沙箱機(jī)制是什么
本文URL:http://weahome.cn/article/jjjpic.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部