Why are public static final array a security hole?

后端 未结 8 1655
盖世英雄少女心
盖世英雄少女心 2020-12-13 13:21

Effective java says:

// Potential security hole!

static public final Thing[] VALUES = { ... };

Can somebody tell me what is t

相关标签:
8条回答
  • 2020-12-13 13:46

    To understand why this is a potential security hole and not just poor encapsulation, consider the following example:

    public class SafeSites {
        // a trusted class with permission to create network connections
        public static final String[] ALLOWED_URLS = new String[] {
            "http://amazon.com", "http://cnn.com"};
    
        // this method allows untrusted code to connect to allowed sites (only)
        public static void doRequest(String url) {
            for (String allowed : ALLOWED_URLS) {
                if (url.equals(allowed)) {
                     // send a request ...
                }
            }
        }
    }
    
    public class Untrusted {
         // An untrusted class that is executed in a security sandbox.
    
         public void naughtyBoy() {
             SafeSites.ALLOWED_URLS[0] = "http://myporn.com";
             SafeSites.doRequest("http://myporn.com");
         }
    }
    

    As you can see, the mistaken use of a final array means that untrusted code can subvert the restriction that the trusted code / sandbox is trying to impose. In this case, this is clearly a security issue.

    If your code is not part of a security critical application, then you could ignore this issue. But IMO this is a bad idea. At some point in the future you (or someone else) might reuse your code in a context where security is a concern. At any rate, this is why the author calls public final arrays a security issue.


    Amber said this in a comment:

    No more a security hole than private would be, if you can read the source code and/or bytecode either way...

    This is not true.

    The fact that a "bad guy" can use source code / bytecodes to determine that a private exists and refers to an array is not sufficient to break security. The bad guy also has to inject code into a JVM that has the required permissions to use reflection. This permission is not available to untrusted code running in a (properly implemented) security sandbox.

    0 讨论(0)
  • 2020-12-13 13:46

    I would also add what Joshua Bloch proposed in Effective Java 3rd edition. Of course we can easily change the value of the array if it is declared as:

    public static final String[] VALUES = { "a", "b" }; 
    
    a.VALUES[0] = "changed value on index 0";
    System.out.println(String.format("Result: %s", a.VALUES[0]));
    

    and we get Result: changed value on index 0

    Joshua Bloch proposed to return copy of array:

    private static final String[] VALUES = { "a", "b" };   
    public static final String[] values()
    {
        return VALUES.clone();
    }
    

    so now when we try:

    a.values()[0] = "changed value on index 0";
    System.out.println(String.format("Result: %s", a.values()[0]));
    

    we get Result: a and that's what we wanted to achieve - the VALUES are immutable.

    There is also nothing bad in declaring public static final a primitives values, Strings or other immutable objects like public static final int ERROR_CODE = 59;

    0 讨论(0)
提交回复
热议问题