Compiler Enforcement Enforcement of the Java Language Rules

This brings us to the need for the bytecode verifier −− the second link in the chain of responsibility of enforcing the rules of the Java language. Normally when the need for the bytecode verifier is discussed, its in terms of an evil compiler −− that is, a compiler that someone has written in such a way that the code produced by the compiler is not legal Java code. The theory is that code from such a compiler could be constructed in order to create and exploit a security hole by ignoring a rule in the Java language. Such an attack might seem to be difficult to achieve in that it would require some detailed knowledge of the Java compiler. It turns out that the evil compiler issue is a red herring −− it doesnt really matter whether such an attack is likely or not because its trivial to create nonconforming Java code with any standard Java compiler. Assume that we have these two classes: package javasec.samples.ch03; public class CreditCard { public String acctNo = 0001 0002 0003 0004; } package javasec.samples.ch03; public class Test { public static void mainString args[] { CreditCard cc = new CreditCard ; System.out.printlnYour account number is + cc.acctNo; } } If we run this code, well create a CreditCard object and print out its account number. Now say that we realize the account number should really have been private, so we go back and change the definition of acctNo to be private and recompile only the CreditCard class. We then have two class files and the Test class file contains Java code that illegally accesses the private instance variable acctNo of the CreditCard class. The above example shows an innocent mistake, but a malicious programmer could use just this technique to produce illegal Java bytecodes. In order to modify the contents of a string, for example, all we need to do is: Copy the java.lang.String source file into our classpath . 1. In the copy of the file, modify the definition of value −− the private array that holds the actual characters of the string −− to be public. 2. Compile this modified class, and replace the class files in the SDK. This entails unpacking rt.jar, copying in the new classes, and repacking rt.jar. 3. Compile some new code against this modified version of the String class. The new code could include something like this: package javasec.samples.ch03; public class CorruptString { public static void modifyStringString src, String dst { for int i = 0; i src.value.length; i++ { if i == dst.value.length return; src.value[i] = dst.value[i]; } } public static void mainString[] args { System.out.printlnOriginal string is + args[0]; modifyStringargs[0], SDO was here; 4. Chapter 3. Java Language Security