Why isn't calling a static method by way of an instance an error for the Java compiler?

后端 未结 12 2050
北海茫月
北海茫月 2020-11-22 06:59

I\'m sure you all know the behaviour I mean - code such as:

Thread thread = new Thread();
int activeCount = thread.activeCount();

provokes

相关标签:
12条回答
  • 2020-11-22 07:39

    It's pretty old topic but still up-to-date and surprisingly bringing higher impact nowadays. As Jon mentioned, it might be just a mistake Java's designers made at the very beginning. But I wouldn't imagine before it can have impact on security.

    Many coders know Apache Velocity, flexible and powerful template engine. It's so powerful that it allows to feed template with a set of named objects - stricly considered as objects from programming language (Java originally). Those objects can be accessed from within template like in programming language so for example Java's String instance can be used with all its public fields, properties and methods

    $input.isEmpty()
    

    where input is a String, runs directly through JVM and returns true or false to Velocity parser's output). So far so good.

    But in Java all objects inherit from Object so our end-users can also put this to the template

    $input.getClass()
    

    to get an instance of String Class.

    And with this reference they can also call a static method forName(String) on this

    $input.getClass().forName("java.io.FileDescriptor")
    

    use any class name and use it to whatever web server's account can do (deface, steal DB content, inspect config files, ...)

    This exploit is somehow (in specific context) described here: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py

    It wouldn't be possible if calling static methods from reference to the instance of class was prohibited.

    I'm not saying that a particular programming framework is better than the other one or so but I just want to put a comparison. There's a port of Apache Velocity for .NET. In C# it's not possible to call static methods just from instance's reference what makes exploit like this useless:

    $input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
    
    0 讨论(0)
  • 2020-11-22 07:40

    There's not option for it. In java (like many other lang.) you can have access to all static members of a class through its class name or instance object of that class. That would be up to you and your case and software solution which one you should use that gives you more readability.

    0 讨论(0)
  • 2020-11-22 07:44

    They cannot make it an error anymore, because of all the code that is already out there.

    I am with you on that it should be an error. Maybe there should be an option/profile for the compiler to upgrade some warnings to errors.

    Update: When they introduced the assert keyword in 1.4, which has similar potential compatibility issues with old code, they made it available only if you explicitly set the source mode to "1.4". I suppose one could make a it an error in a new source mode "java 7". But I doubt they would do it, considering that all the hassle it would cause. As others have pointed out, it is not strictly necessary to prevent you from writing confusing code. And language changes to Java should be limited to the strictly necessary at this point.

    0 讨论(0)
  • 2020-11-22 07:44

    Short answer - the language allows it, so its not an error.

    0 讨论(0)
  • 2020-11-22 07:45

    Likely for the same logical that makes this not an error:

    public class X
    {
        public static void foo()
        {
        }
    
        public void bar()
        {
            foo(); // no need to do X.foo();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 07:45

    The really important thing, from the compiler's perspective, is that it be able to resolve symbols. In the case of a static method, it needs to know what class to look in for it -- since it's not associated with any particular object. Java's designers obviously decided that since they could determine the class of an object, they could also resolve the class of any static method for that object from any instance of the object. They choose to allow this -- swayed, perhaps, by @TofuBeer's observation -- to give the programmer some convenience. Other language designers have made different choices. I probably would have fallen into the latter camp, but it's not that big of a deal to me. I probably would allow the usage that @TofuBeer mentions, but having allowed it my position on not allowing access from an instance variable is less tenable.

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