| |
|
Using the Java ByteCode Verifier To Prevent Malicious Access |
|
|
|
Written by Atul Kahate
|
|
Jan 29, 2007 at 12:00 AM |
|
Page 2 of 2 In other words, it ensures that a class can access only the entities
that it should be allowed to access. It should be pointed out that
chances of malicious code attempting to violate access specifiers are
more on the client side. Therefore, the bytecode verifier is turned on
by default when executing Java code as applets inside browsers
(client). However, this is made optional in Java applications, whereby
we can use a switch called as -verify that turns the verification on.
The Java bytecode verifier ensures
that the access specifiers are not violated...
-verify switch turns verification on
It is quite interesting to know that even many experts of the Java
programming language are not aware of a possible hole in the Java
security model with reference to accessibility. We shall demonstrate
this with a simple example.
Let us first create two simple Java classes named Sufferer and
Attacker. They are shown below.
public class Sufferer { public String test;
public Sufferer () { test = "I am attacked!"; } }
public class Attacker {
public static void main (String[] args) { Sufferer sufferer = new Sufferer (); System.out.println (sufferer.test); } }
Now let us compile both the classes:
C:> javac Sufferer.java Attacker.java
Let us run the example:
C:> java Attacker
The example would run with no problems, producing the output I am
attacked! This is quite normal. However, what we shall do next is quite
interesting. Let us change the access modifier in the Sufferer class
from public to private. The modified class looks as follows.
public class Sufferer { private String test;
public Sufferer () { test = "I am attacked!"; } }
Let us recompile just Sufferer, but not Attacker:
C:> javac Sufferer.java
Let us rerun the example:
C:> java Attacker
What do you think will happen? We should get an error that the Attacker
class cannot access the private data member test of the Sufferer class.
But the example actually runs fine! It produces the same output as
before! This is something that most experts also find it hard to
believe.
Here's something that most experts
also find it hard to
believe...
Why does this happen? It is the responsibility of the bytecode
verifier to decide if a class attempts to access controlled/restricted
entities. By default, the bytecode loaded from the file system is not
verified. We need to explicitly ask the bytecode verifier to come into
action.
The Java bytecode verifier comes to the rescue, if we use the -verify
switch. We can now rerun the example as follows:
C:> java -verify Attacker
Now the bytecode verifier comes into action at run time, and stops the
Attacker class from trying to access the private data member named test
of the Sufferer class. We get the following run time exception:
Exception in thread "main" java.lang.IllegalAccessError: tried to
access field Sufferer.test from class Attacker at
Attacker.main(Attacker.java:5)
Instantiate Java
applications with the verify switch in order to protect private data
members...
Thus, it is important to know that we must instantiate Java
applications with the verify switch in order to protect private data
members from being accessed by malicious code. ---
Atul
Kahate writes about Java Security in this monthly
column on IndicThreads.com. Atul is the author of 13 books including
"Cryptography
and Network Security".
He is currently a Project Manager at i-flex solutions limited, Pune,
India. Atul can be reached at (akahate at gmail
dot com)
--- Related JAVA CRYPTOGRAPHY: A BIRD’S EYE VIEW
Sights and Sounds Of The IndicThreads.com Conference On Java Technology
|
Comment by 'Guest' on 2007-01-29 10:37:38 If -verify helps protect private variables why is it not enabled by default? Are there any drawbacks? Looks like a security hole is kept open unnecessarily :? | Comment by GUEST on 2007-09-13 05:29:24 Sir, can you clean remove both the class files first then change in Sufferer.java, public to private variable, and then compile again. Even if you have Sufferer.class which has private variable, then change in Sufferer.java as public and compile Attacker.java its working.. why?
| Comment by GUEST on 2007-09-17 01:08:27 When we compile Attacker.java, the Sufferer is compiled.
|
|
|
|
|