System.setProperty在java中是安全的吗?

时间:2013-02-23 11:13:48

标签: java security

在java中传递某些类之间的值,我们可以使用System.setProperty。但是使用System.getProperties()我们可以获得所有系统属性。因此,如果我使用任何第三方API意味着他们也可以访问我的属性,他们也可以更改。那么System.setProperty安全吗?

4 个答案:

答案 0 :(得分:5)

这取决于您的安全意义。

  1. 优良作法 1 将系统属性对象视为只读,但您不能依赖第三方库来执行此操作。

  2. 如果您担心看到或更改应用程序属性的“受信任”第三方代码,请不要使用“系统属性”来表示它们。创建自己的Properties对象并将属性放在那里。这可能是最简单的方法。

  3. 如果使用沙盒,则可以防止不受信任的代码访问“系统属性”...前提是您的代码不会将“系统属性”对象泄露给不受信任的代码。 (访问检查在System方法...)

  4. 中实现
  5. 如果您提到这种安全性,则Properties对象是线程安全的。


  6. 1 - 有时需要以编程方式修改系统属性。但是,通过执行此操作,您最终可能会遇到脆弱的应用程序。系统属性通常用于在初始化期间配置JVM服务。如果类初始化的顺序由于某种原因而改变,您可能会发现您的应用程序代码现在设置属性太晚了。如果可能,最好通过-D命令行参数设置属性。

答案 1 :(得分:2)

如果您需要担心库的行为,您需要了解并使用安全策略和SecurityManager。除此之外,这将允许您限制System.setProperty

的使用

答案 2 :(得分:0)

根据documentation

通常,请注意不要覆盖系统属性。

  

setProperties方法更改了系统属性集   当前正在运行这些变化并不持久。那   是,在应用程序中更改系统属性不会   影响Java解释器的未来调用   其他申请。运行时系统重新初始化系统   属性每次启动时。如果更改系统属性   要持久化,那么应用程序必须将值写入   退出前的一些文件,并在启动时再次读取它们。

您的担忧是正确的,某些第三方库可能会覆盖您的应用正在使用的属性。使用某种命名约定来区分属性文件中定义的键始终是一种很好的做法。

对问题进行非常简单的模拟

public class TestApp {
    public static void main(String args[]) throws InterruptedException {
        TestApp app = new TestApp();
        app.new ThirdPartyLib("thirdParty").start();
        while (true) {
            Thread.currentThread().sleep(500);
            System.setProperty("test", "orignalProperty");
            System.out
                    .format("Thread Name  '%s' setting the property with value '%s' \n ",
                            Thread.currentThread().getName(),
                            System.getProperty("test"));
        }
    }

    class ThirdPartyLib extends Thread {
        public ThirdPartyLib(String threadName) {
            super(threadName);
        }

        @Override
        public void run() {
            super.run();
            while (true) {
                Thread.currentThread();
                try {
                    Thread.sleep(400);
                    System.setProperty("test", "modifiedProperty");
                    System.out
                            .format("Thread Name  '%s' setting the property with value '%s' \n ",
                                    Thread.currentThread().getName(),
                                    System.getProperty("test"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

将导致输出低于 - 可能不是预期的输出,我也很难调试

 Thread Name  'thirdParty' setting the property with value 'modifiedProperty' 
 Thread Name  'main' setting the property with value 'orignalProperty' 
 Thread Name  'thirdParty' setting the property with value 'modifiedProperty' 
 Thread Name  'main' setting the property with value 'orignalProperty' 
 Thread Name  'thirdParty' setting the property with value 'modifiedProperty' 
 Thread Name  'thirdParty' setting the property with value 'modifiedProperty' 
 Thread Name  'main' setting the property with value 'orignalProperty' 

答案 3 :(得分:0)

我不会依赖使用系统属性在线程之间共享信息。我尝试在一个线程中创建一个属性,即使经过10秒也找不到另一个线程。其他人已经回答了修改线程可用的系统属性值的行为。