Can’t do what?

Ho boy! I’ve just come across this issue while working on a new Java JSon library. One of my tests cases failed on something that I was not expecting it to.

Basically, it happens that one can inject all sorts of objects in a specialized Collection (and I’m guessing that the same is true for all generics) through the Java Reflection API.

package BreakItNow;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class BreakItNow {

	public List<ObjectOne> list = new ArrayList<ObjectOne>();
	
	public static void main(String... args) throws Exception {
		BreakItNow bin = new BreakItNow();
		
		// Not a problem, I can do that!
		bin.list.add(new ObjectOne());
		
		// Not a problem, you can't do that!
		Object o = new ObjectTwo();
		try {
			bin.list.add((ObjectOne)o);
		} catch (ClassCastException e) {}
		
		// Ho yes I can!
		Field field = BreakItNow.class.getField("list");
		for (Method m : field.getType().getDeclaredMethods()) {
			if (m.getName().equals("add") && m.getParameterTypes().length == 1) {
				m.invoke(bin.list, o);
			}
		}
		
		System.out.println(bin.list);
		for (Object obj : bin.list) {
			if (obj instanceof ObjectOne)
				System.out.println(ObjectOne.class.cast(obj).text);
			else
				System.out.println(ObjectTwo.class.cast(obj).text + " <- See, I told ya!");
		}
	}
	
}

And the output will look like:

[BreakItNow.ObjectOne@1172e08, BreakItNow.ObjectTwo@cf2c80]
ObjectOne
ObjectTwo <- See, I told ya!

Beautiful, right?

This happens because of Generics Type Erasure (thanks H9i) and can be fixed by making use of Generics Wrappers.

To enforce type checking and prevent this situation the above list should be created in a checked wrapper:

public List<ObjectOne> list = Collections.checkedList(new ArrayList<ObjectOne>(), ObjectOne.class);

So, it is obvious that Java engineers have chosen performance over default security. Quite often developers will simply assume that by the simple fact of having a specialized list, then their type will be enforced, which is not the case. Because of this, I would think that the security implications are quite significant since it increases the probability of creating non-secure code.

Planning and preparing ahead by using automatic tools that will enforce secure coding rules should be taken in consideration in projects of sensitive nature or in layers that require such practice.

Advertisements

About CrazyPenguin

Software Engineer
This entry was posted in J2EE, Java and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s