You are here : Home » Learning security » Applications » Java » Modify any Java class field using reflection.

Modify any Java class field using reflection.

D 13 January 2011     H 20:46     A Emeric Nasi     C 4 messages


agrandir


License : Copyright Emeric Nasi, some rights reserved
This work is licensed under a Creative Commons Attribution 4.0 International License.
Creative Commons License

I. Reflection and Java security

For most Java developers, Java security comes from the use of keywords such as "private, protected, or final".
For example a field declared :
private static String state;
The field called "state" is a class variable, with the given keywords, it should only be accessible by other instance objects of the same class.

Another example :
private final String name="MyClass";

In this example the field "name" can only be accessed by another code in the same object, and it has the "final" keyword so it cannot be modified once it is set (a real Java constant has both the keywords "static" and "final").

These examples shows that Java data access security is guaranteed by the language keywords, however this statement is not true because of Java "reflection".
Reflection is a Java feature that allows a code to examine itself dynamically and modify its references and properties at runtime.
Reflection is a direct part of the Java language. The reflection package is java.lang.reflect. This package provides objects that can be used to list any fields inside a class, invoke any class methods or access and modify any fields, and when I say any I mean all of them, even private ones.

II. Use reflection to modify any class/object field.

II.1 Our scope

The java.lang.reflect classes allows you do do a lot more things than just access to class fields. This is just a little part of the enormous possibilities of reflection, the goal here is to show that reflection can "break" classic keyword security.
The only include that is needed for this article codes is :

  1. import java.lang.reflect.Field;

II.2 Access and modify any class variables

A class variable is a variable that is common to all instances of this class, it is defined with the "static" keyword.
The code below can be used to access any class variable :

  1.  
  2. /**
  3.   * Returns an object containing the value of any static field (even private).
  4.   * @param className The complete name of the class (ex. java.lang.String)
  5.   * @param fieldName The name of a static field in the class
  6.   * @return An Object containing the static field value.
  7.   * @throws SecurityException .
  8.   * @throws NoSuchFieldException .
  9.   * @throws ClassNotFoundException .
  10.   * @throws IllegalArgumentException .
  11.   * @throws IllegalAccessException .
  12.   */
  13. public static Object getStaticValue(final String className, final String fieldName) throws SecurityException, NoSuchFieldException, ClassNotFoundException,
  14.  
  15. // Get the private field
  16. final Field field = Class.forName(className).getDeclaredField(fieldName);
  17. // Allow modification on the field
  18. field.setAccessible(true);
  19. // Return the Obect corresponding to the field
  20. return field.get(Class.forName(className));
  21. }
  22.  

Download

In this code, the essential line is "field.setAccessible(true);". The setAccessible() method disables usual languages security checks and allows the field to be accessed from any other class.
Note also the getDeclaredField() method that is really useful and allows you to access via reflection to a Field object representing any field that is declared inside a Class.
We saw we could grab any field value, but can we also modify them? the answer is yes. For that you can use the next code :

  1.  
  2. /**
  3.   * Use reflection to change value of any static field.
  4.   * @param className The complete name of the class (ex. java.lang.String)
  5.   * @param fieldName The name of a static field in the class
  6.   * @param newValue The value you want the field to be set to.
  7.   * @throws SecurityException .
  8.   * @throws NoSuchFieldException .
  9.   * @throws ClassNotFoundException .
  10.   * @throws IllegalArgumentException .
  11.   * @throws IllegalAccessException .
  12.   */
  13. public static void setStaticValue(final String className, final String fieldName, final Object newValue) throws SecurityException, NoSuchFieldException,
  14. // Get the private String field
  15. final Field field = Class.forName(className).getDeclaredField(fieldName);
  16. // Allow modification on the field
  17. field.setAccessible(true);
  18. // Get
  19. final Object oldValue = field.get(Class.forName(className));
  20. // Sets the field to the new value
  21. field.set(oldValue, newValue);
  22.  
  23. }
  24.  

Download

Here, the Field.get() method is used to grab the object contained in the field. The set() method overrides this object with another Object (newValue) we passed in parameters.

II.3 Access and modify any instance variables

In the previous section we saw that we could access and modify any static field. We can do the same thing for non-static fields that is, instance variables. The example codes works basically like the previous ones except that instead of manipulating a Class, we are going to manipulate an Object, instance of the Class.

  1.  
  2. /**
  3.   * Returns an object containing the value of any field of an object instance (even private).
  4.   * @param classInstance An Object instance.
  5.   * @param fieldName The name of a field in the class instantiated by classInstance
  6.   * @return An Object containing the field value.
  7.   * @throws SecurityException .
  8.   * @throws NoSuchFieldException .
  9.   * @throws ClassNotFoundException .
  10.   * @throws IllegalArgumentException .
  11.   * @throws IllegalAccessException .
  12.   */
  13. public static Object getInstanceValue(final Object classInstance, final String fieldName) throws SecurityException, NoSuchFieldException,
  14.  
  15. // Get the private field
  16. final Field field = classInstance.getClass().getDeclaredField(fieldName);
  17. // Allow modification on the field
  18. field.setAccessible(true);
  19. // Return the Obect corresponding to the field
  20. return field.get(classInstance);
  21.  
  22. }
  23.  

Download

  1.  
  2. /**
  3.   * Use reflection to change value of any instance field.
  4.   * @param classInstance An Object instance.
  5.   * @param fieldName The name of a field in the class instantiated by classInstancee
  6.   * @param newValue The value you want the field to be set to.
  7.   * @throws SecurityException .
  8.   * @throws NoSuchFieldException .
  9.   * @throws ClassNotFoundException .
  10.   * @throws IllegalArgumentException .
  11.   * @throws IllegalAccessException .
  12.   */
  13. public static void setInstanceValue(final Object classInstance, final String fieldName, final Object newValue) throws SecurityException,
  14. // Get the private field
  15. final Field field = classInstance.getClass().getDeclaredField(fieldName);
  16. // Allow modification on the field
  17. field.setAccessible(true);
  18. // Sets the field to the new value for this instance
  19. field.set(classInstance, newValue);
  20.  
  21. }
  22.  

Download

III. Prevent reflection

Reflection is a very powerful feature and a lot of Java frameworks use it. However, an "evil" code can also use it to break the security of your application and access and modify any field and a lot more things (invoke any methods, list all class content, etc).
The only way to prevent reflection is to use a securitymanager. By default code using reflection needs particular security permissions.
In our example, both the getDeclaredField() method and the setAccessible() method contain an inner security check that will throw a SecurityException if called by a code that is not authorized by the securitymanager.
If you want to look at some example of securitymanager that authorizes reflection for particular jars you should read the article : Spring and Hibernate Tomcat security manager.

IV. Example : Disable Java security

The best example to show that reflection is a dangerous feature is to show that all the security mechanisms of Java, relying on the security manager, can be disabled using a single call to the setStaticValue() method previously described in this article.
The entire language security of Java relies on security checks using a static value inside the java.lang.System class.
The usual security checks maid by sensible functions are :

  • Test if a call to System.getSecurityManager() returns null.
  • If returned value is null, the function considers security is deactivated.
  • If the return value is not null, the SecurityManager element returned by the function is used to know what is authorized and what is not.

The System.getSecurityManager() method simply returns the value of a static private variable of the System class, security.
So, that means, disabling Java language security is as simple as setting the security variable to null.

  1. setStaticValue("java.lang.System", "security", null);

Thats all!

Also in this section

8 January 2011 – Enable securitymanager for Spring and Hibernate

10 November 2010 – Implement hash service using JCE

3 Forum posts

Any message or comments?
pre-moderation

This forum is moderated before publication: your contribution will only appear after being validated by an administrator.

Who are you?
Your post