我找到了90%的答案。簡單的答案是,我們需要建立許多權限,但這個過程很明顯,很容易隱藏在某個實用程序類中。如果它在某個標準的地方可用,那就太好了,不過哦。 樂嘆息。
所有我們需要做的是類路徑和EXT DIR檢查系統屬性(並添加FilePermissions(只讀)爲他們),進行必要的SecurityPermissions(只讀),最後加PropertyPermissions(只讀僅限於)所有系統屬性。剩下的只是一些非常明顯的權限,例如,授予臨時目錄的r/w/d(但不執行)權限,授予對本地主機的「解析」訪問權等。
真正安全的沙箱可能不會希望使所有系統屬性可讀,但這很容易修復,並留給讀者。
public class LoggingSecurityManager extends SecurityManager {
private AccessControlContext ctx;
private Properties properties = new Properties;
private Set missingProperties = new HashSet();
public LoggingSecurityManager() {
properties.add(
new FilePermission(System.get("java.io.tmpdir") + "/-", "read,write,delete"));
// maybe...
properties.add(
new FilePermission(System.get("user.home") + "/-", "read,write,delete"));
addSystemPropertyPermissions();
addSecurityPermissions();
addClassPathPermissions();
addOtherPropertyPermissions();
permissions.add(new RuntimePermission("accessClassInPackage.sun.reflect"));
permissions.add(new RuntimePermission("accessClassInPackage.sun.jdbc.odbc"));
permissions.add(new RuntimePermission("accessClassInPackage.sun.security.provider"));
permissions.add(new SocketPermission("localhost", "resolve"));
permissions.add(new NetPermission("getProxySelector"));
ctx = new AccessControlContext(new ProtectionDomain[] {
new ProtectionDomain(null, permissions)
});
}
/**
* Add read-only permission to read system properties.
* We may want to filter this list to remove sensitive information
*/
public void addSystemPropertyPermissions() {
for (Object key : Collections.list(System.getProperties().keys())) {
permissions.add(new PropertyPermission((String) key, "read"));
}
}
/**
* Add read-only permissions for initializing security.
*/
public void addSecurityPermissions() {
permissions.add(new SecurityPermission("getPolicy"));
permissions.add(new SecurityPermission("getProperty.random.source"));
permissions.add(new SecurityPermission("getProperty.securerandom.source"));
for (int i = 1; i < 10; i++) { // configurable limit?
permissions.add(new SecurityPermission("getProperty.security.provider." + i));
}
String s = Security.getProperty("securerandom.source");
if ((s != null) && s.startsWith("file:/")) {
permissions.add(new FilePermission(s.substring(5), "read"));
}
// should have been covered already but wasn't....
permissions.add(new FilePermission("/dev/random", "read"));
}
/**
* Add read-only permissions for everything on classpath.
*/
public void addClassPathPermissions() {
permissions.add(new FilePermission(String.format("%/lib/-",
System.getProperty("java.home")), "read"));
// add standard class path.
String pathSep = System.getProperty("path.separator");
for (String entry : System.getProperty("java.class.path").split(pathSep)) {
File f = new File(entry);
if (f.isFile()) {
permissions.add(new FilePermission(entry, "read"));
} else if (f.isDirectory()) {
permissions.add(new FilePermission(String.format("%s/-", entry), "read"));
} // or could be neither fish nor fowl
}
// add endorsed extensions.
for (String dir : System.getProperty("java.ext.dirs").split(pathSep)) {
permissions.add(new FilePermission(String.format("%s/-", dir), "read"));
}
}
/**
* Add other standard properties.
*/
public void addOtherPropertyPermissions() {
permissions.add(new PropertyPermission("jdbc.drivers", "read"));
permissions.add(new PropertyPermission("java.security.egd", "read"));
permissions.add(new PropertyPermission("socksProxyHost", "read"));
}
}
有一個可怕的少點。這些權限打開了大規模破壞的大門。
// ------------ S C A R Y - B L O C K -----------
permissions.add(new ReflectPermission("suppressAccessChecks")); (!!)
permissions.add(new RuntimePermission("createClassLoader")); (!!)
permissions.add(new SecurityPermission("putProviderProperty.SUN"));
permissions.add(new RuntimePermission("readFileDescriptor"));**
permissions.add(new RuntimePermission("writeFileDescriptor"));
// ------------ S C A R Y - B L O C K -----------
我還沒有決定這裏的最佳行動方案。我認爲我可以做的是覆蓋checkPermission方法,並在看到前兩個權限(至少)時查看調用堆棧。如果它們來自JDK內部的話,它們可能是安全的。如果來自用戶代碼,它們很可能會有問題。
不知道我是否按照100%的方案,但它可能是問題不是構造函數,而是類加載(通常在給定類首次引用時發生)?如果是這樣,你可以簡單地在doPrivileged塊之外引用所需的類,並將構造函數留在其中。 – 2010-09-29 01:36:09
不,它是每個構造函數。甚至像「新的String(foo)」的東西。 (我知道,愚蠢,但我試圖想出一些絕對有用的東西。) – bgiles 2010-10-05 21:06:22