该文章有关Java安全说:
只要尝试执行危险操作,Java库中的代码就会查询安全管理器.
那么,这究竟意味着什么呢?比如说,如果我已经实现了自己的安全管理器并为整个JVM启用了它.现在,java运行时是否为每个java调用(如System.out.println()等)查询我的安全管理器,或者它只参考dangerous像System.exit(),文件操作等api调用?
编辑:让我澄清一下我的问题,
我不是在质疑安全管理员的可能性.我只是询问是否单独对危险的api进行了安全检查,或者是为每个方法调用进行了安全检查.在具有大量代码的应用程序中,哪种情况会导致性能大幅下降.
我试图禁止System.exit(int);在一些罐子里打电话.
这些罐子将由外部团队开发,并由我们的"容器"应用程序加载.
我的第一反应是使用java安全管理器:
-Djava.security.manager-Djava.security.debug=all
Run Code Online (Sandbox Code Playgroud)
用最简单的${user.home}/.java.policy文件:
grant {};
Run Code Online (Sandbox Code Playgroud)
虽然我不能再调用System.getProperties()(因为我没有java.util.PropertyPermission),我可以做一个System.exit(0)!!
该选项java.security.debug=all提供以下控制台:
scl: getPerms ProtectionDomain (file: my-bin-path <no sign certificates>)
sun.misc.Launcher $ AppClassLoader @ 10385c1
<no principals>
java.security.Permissions @ 15b7986 (
(java.lang.RuntimePermission exitVM)
(java.io.FilePermission \my-bin-path\- read)
)
Run Code Online (Sandbox Code Playgroud)
为什么my-bin-path中的所有类都已java.lang.RuntimePermission exitVM授予?????
谢谢
你碰巧知道解释为什么java安全管理器不禁止创建新线程或启动它们吗?新的FileWriter在安全管理器下,但新的Thread()和threadInstance.start()都不是更安全的安全管理器,并且可以调用.
我目前正在开发一个小型Java应用程序,其中必须与不受信任的代码一起运行受信任的代码.为了实现这一点,我已经安装了一个自定义SecurityManager,它会SecurityException在检查权限时抛出.
作为可信代码和不可信代码之间的桥梁,我有一个Constructor.newInstance()用于实例化不受信任类型的对象的线程.在进行此调用时,安全管理器配置为阻止所有内容.有趣的是,我试图创建对象的前15次Constructor.newInstance(),一切正常,但第16次我得到了SecurityException.
我已经成功地将其归结为一个简单的测试程序:
import java.lang.reflect.*;
import java.security.*;
public class Main {
/* Track how many instances have been created so that we can see when the exception
* is thrown.
*/
private static int numInstances = 0;
public Main() {
System.out.println("Number created: " + ++numInstances);
}
public static void main(String[] args) {
/* Get the constructor for Main so that we can instantiate everything
* later on.
*/
Constructor<Main> ctor; …Run Code Online (Sandbox Code Playgroud) 目前我正在尝试编写Sandbox来运行不受信任的Java代码.我们的想法是将Java应用程序与访问文件系统或网络套接字隔离开来.我目前的解决方案是重写了SecurityManager,禁止对IO或网络的任何访问.
现在我不想禁止,但是要将调用重定向到文件系统,即如果应用程序想要写入"/home/user/application.txt",则文件的路径应替换为"/ temp/trusted_folder /"之类的内容. application.txt".所以基本上我想允许应用程序仅在某个特定文件夹中访问文件系统,并将所有其他调用重定向到此文件夹.
所以这里是来自FileOutputStream类的方法,其中询问SM,是否有写入给定路径的权限.
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
fd = new FileDescriptor();
fd.incrementAndGetUseCount();
this.append = append;
if (append) {
openAppend(name);
} else {
open(name);
}
}
Run Code Online (Sandbox Code Playgroud)
显然,SM不能访问FileOutputStream并且不能更改方法中的内部变量(如名称或文件)或以某种方式影响执行顺序,除了抛出SecurityException.我明白,访问内部字段违反了面向对象的原则,我明白,局部变量是可见的,只存在于声明它们的方法中.
所以我的问题是:有没有办法让Security Manager替换对文件系统的调用?如果没有,我可以使用任何其他方法来做到这一点吗?
我希望我很清楚.
使用SecurityManager时是否存在性能损失?
我需要以下内容:
public class ExitHelper {
public ExitHelper() {
System.setSecurityManager(new ExitMonitorSecurityManager());
}
private static class ExitMonitorSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {}
@Override
public void checkPermission(Permission perm, Object context) {}
@Override
public void checkExit( final int status ) {
// this is the part I need and I don't care much about the performance issue of this method
}
}
Run Code Online (Sandbox Code Playgroud)
这会对我的计划产生巨大影响吗?
例如,该程序确实打开了很多文件.如果我启用SecurityManager并在那里放入一些日志,我可以调用这些方法.真的很多.在这两种方法的记录中丢失了正常的日志记录.因此,将SecurityManager置于适当的位置意味着可以进行大量的调用.它会比默认的SecurityManager慢吗?(默认情况下有吗?)
这是如何运作的?将检查程序的哪个部分的权限和频率?我关注两个checkPermission(...)方法.
我无法解释这一点,但我在其他人的代码中发现了这种现象:
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.util.stream.Stream;
import org.junit.Test;
public class TestDidWeBreakJavaAgain
{
@Test
public void testIoInSerialStream()
{
doTest(false);
}
@Test
public void testIoInParallelStream()
{
doTest(true);
}
private void doTest(boolean parallel)
{
Stream<String> stream = Stream.of("1", "2", "3");
if (parallel)
{
stream = stream.parallel();
}
stream.forEach(name -> {
try
{
Files.createTempFile(name, ".dat");
}
catch (IOException e)
{
throw new UncheckedIOException("Failed to create temp file", e);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
在启用安全管理器的情况下运行时,仅仅调用parallel()流,或者parallelStream()从集合中获取流时,似乎可以保证所有执行I/O的尝试都会抛出SecurityException.(最有可能的,它调用任何方法可以抛出 …
关于这个问题,我一直在阅读关于Stackoverflow的很多问题,但无法找到解决方案或解决我的问题.如果已经有人,如果有人提示,我将不胜感激......
我的问题/问题是,是否可以完全禁用不值得信赖的代码的反射?功能如getDeclaredMethods()(见test.java).我已经有了一个Java安全管理器,如果代码试图写/读/等,它会抛出安全例外....
如果有可能,有人可以告诉我怎么样?
布鲁诺
test.java
TestClass cls = new TestClass();
Class c = cls.getClass();
// returns the array of Method objects
Method[] m = c.getDeclaredMethods();
for(int i = 0; i < m.length; i++) {
System.out.println("method = " + m[i].toString());
}
Run Code Online (Sandbox Code Playgroud) 有没有办法让Java中的SecurityManager根据调用setAccessible()的详细信息有选择地授予ReflectPermission("suppressAccessChecks")?我认为没有办法做到这一点.
对于某些沙盒代码,它将非常有用(例如运行各种动态JVM语言)以允许调用setAccessible()反射API,但仅当在发起的类的方法/字段上调用setAccessible()时在沙盒代码中.
除非选择性授予ReflectPermission("suppressAccessChecks"),否则是否有任何其他建议?在所有情况下,如果SecurityManager.checkMemberAccess()具有足够的限制性,那么授予它是否安全?
我对Java(6+)如何分发其安全框架感到困惑.一方面,您有以下包(及其各自的子包和类型):
java.security.*javax.security.*而另一方面,您可以java.lang.SecurityManager使用其他非安全包(例如java.lang)中的其他安全相关类型.
那么,有几个问题:
java.security和之间有什么区别javax.security?何时使用每种类型?java.lang,还有其他任何以安全为中心的类型出现的软件包,如果有的话,它们是什么?提前致谢!
java ×10
securitymanager ×10
reflection ×3
security ×3
sandbox ×2
java-8 ×1
java-stream ×1
jce ×1
policies ×1