java.lang.SecurityManager中的初始化字段是什么?

时间:2018-07-01 06:20:46

标签: java security initialization finalizer securitymanager

java.lang.SecurityManager中,有一个布尔值字段,称为Initialized。

public class SecurityManager {

    /*
     * Have we been initialized. Effective against finalizer attacks.
     */
    private boolean initialized = false;
    //some code
    /**
     * Constructs a new <code>SecurityManager</code>.
     *
     * <p> If there is a security manager already installed, this method first
     * calls the security manager's <code>checkPermission</code> method
     * with the <code>RuntimePermission("createSecurityManager")</code>
     * permission to ensure the calling thread has permission to create a new
     * security manager.
     * This may result in throwing a <code>SecurityException</code>.
     *
     * @exception  java.lang.SecurityException if a security manager already
     *             exists and its <code>checkPermission</code> method
     *             doesn't allow creation of a new security manager.
     * @see        java.lang.System#getSecurityManager()
     * @see        #checkPermission(java.security.Permission) checkPermission
     * @see java.lang.RuntimePermission
     */
    public SecurityManager() {
        synchronized(SecurityManager.class) {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                // ask the currently installed security manager if we
                // can create a new one.
                sm.checkPermission(new RuntimePermission
                                   ("createSecurityManager"));
            }
            initialized = true;
        }
    }
    //some code
}

因此,显然,默认情况下,初始化字段将为false,但是如果实例化通过安全检查并成功,则初始化字段将被分配为true。初始化字段上方只有一条评论,说它对终结器攻击有效,并且未提供有关该字段的更多描述。

我在互联网上搜索了finalizer attacks。据我了解,我们不应该依赖不受信任的代码可以覆盖的方法。但是它与初始化字段有何关系?我仍然可以继承java.lang.SecurityManager,并且如果安装了SecurityManager但允许通过反射访问私有字段,则应该可以编辑初始化的字段。那么对终结器攻击如何有效?

1 个答案:

答案 0 :(得分:1)

这是一种较旧的保护技术: https://www.ibm.com/developerworks/java/library/j-fv/j-fv-pdf.pdf

简而言之,终结器攻击是当您重写对象的finalize()方法时,该方法用作GC调用以释放本地资源的析构函数。但是,一旦您继承了子类或对其进行了重写,则原始代码的不变式/“承诺”将不再成立。

  

如何避免攻击

     

直到Java语言规范(JLS)的第三版发布   Java SE 6中实施的唯一避免攻击的方法-使用   initialized标志,禁止子类化或创建final   终结器-令人满意的解决方案。

     

使用初始化标志:

     

避免攻击的一种方法是使用initialized标志,即   正确创建对象后,将其设置为true。每种方法   该类首先检查是否设置了initialized并抛出一个   如果不是,则为例外。这种编码写起来很累,是   容易被意外遗漏,并且不会阻止攻击者   该方法的子类。