Java reflection and security issues

1. Java reflection mechanism

The Java reflection mechanism means that in the running state, for any class, you can know all the properties and methods of this class; for any object, you can call any of its methods and properties; this dynamically acquired information and dynamic The function of calling the method of the object is called the reflection mechanism of the java language.

A very important point of the reflection mechanism is "runtime", which allows us to load, explore and use .class files that are completely unknown during compilation when the program is running. To sum it up in one sentence, reflection can realize that the properties and methods of any class can be known at runtime.

2. Advantages and disadvantages of reflection mechanism

We who are new to reflection may have a question, why use reflection to create objects directly? At this time, it involves the concept of dynamic compilation and static compilation in Java. Let's briefly talk about it.

Static compilation: Determine the type and bind the object at compile time.

Dynamic compilation: determine the type and bind the object at runtime. It maximizes the flexibility of Java, embodies polymorphism, and reduces the coupling between classes.

advantage:

The reflection mechanism can realize dynamic creation and compilation of objects, which shows great flexibility, especially for J2EE developers, whose flexibility is very obvious. For example, in the development of a large-scale software, when the program is compiled and released, if some functions need to be updated in the future, we cannot ask the user to uninstall the previous software and reinstall the new version. If static is used, the entire program needs to be recompiled once to realize the function update, but if the reflection mechanism is used, it does not need to be uninstalled, and only needs to be dynamically created and compiled at runtime to realize the function.

shortcoming:

have an impact on performance. The reflection mechanism is actually an interpretation operation. We tell the JVM what we want to do and they set our requirements. Such operations are always slower than just doing the same operations directly

3. Reflection mechanism and deserialization vulnerability

The key functions of the deserialization vulnerability:

writeObject() serialization, output Object into Byte stream

readObject() deserializes and outputs Byte stream as Object

Use the reflection mechanism to rewrite the readObject method, add the function Runtime.getRuntime() that can execute commands, and execute the calc.exe command to call out the calculator

Personal blog recommendation: boiled egg's blog

As can be seen from the above deserialization vulnerability, Java reflection can indeed access private methods and properties, which is one of the methods to bypass the second-level security mechanism. It is actually something similar to a "backdoor" left by Java itself for a certain purpose, or to facilitate debugging. In any case, its principle is to turn off access security checks.

In general, when we find a vulnerability and want the program to implement command execution, there are two directions to work hard

1. Control code and function: just like named injection and other injection vulnerabilities, data is executed as code; or readObject is rewritten like the demo code above, and custom code is added

2. Control input, data, and variables: use the existing functions and logic in the code, and realize process control by changing the form of the input content (different inputs will follow different logic processes and execute codes in different code blocks)

For Java deserialization vulnerabilities, this falls into the category of controlled data entry. When calling the reflection mechanism to trigger a vulnerability, he has two basic points that must be met:

1. There is a serializable class, and the class rewrites the readObject() method (because there is no code injection, you can only find out whether there is such a class in the existing code logic)

2. The method.invoke function appears in the logic of the rewritten readObject() method, and the parameters are controllable.

4. Reflective Security

After reading the above content, we should sincerely sigh that the Java reflection mechanism is really too powerful. However, if we have a certain awareness of security, we will find that the powerful mechanism of Java seems a bit too much.

Security is a more complex issue when dealing with reflection. Reflection is often used by framework-type code, and because of this, we might want the framework to have full access to the code, regardless of normal access restrictions. In other cases, however, uncontrolled access can pose a serious security risk.

Because of these conflicting requirements, the Java programming language defines a multilevel approach to dealing with reflection security. The basic pattern is to enforce the same restrictions on reflection that apply to source code access:

1. Access to class public components from any location

2. There is no access to any private components outside the class itself

3. Limited access to protected and packaged (default access) components

Java is a safer language than C++. This is closely related to their operating mechanism. C++ runs locally, which means that almost all programs have the same permissions theoretically. Since Java runs in a virtual machine and does not directly contact the outside world, the operating environment of Java is actually a "sandbox" environment. And as a security model of Java, it includes a series of security components such as bytecode verifier, class loader, security manager, access controller, etc., so it seems that Java's security mechanism is more complicated.

‍Okay, the above is all the content of this article, I hope it will be helpful to everyone, and I hope you will give a lot of support to Code Farmer's House . Your support is the driving force for my creation! I wish you all a happy life!   

Guess you like

Origin blog.csdn.net/wuxiaopengnihao1/article/details/127920887