Byte Code Verifier
The verifier checks byte code at a number of different levels. The verification is done by the client machine after compilation. Although someone could rewrite the compiler to get around the language specifications to produce malicious code, the code would not be executed, since the verification is done after the compilation and it is the client's machine that does the verification.
The client machine runs the Java byte code using a virtual (simulated) Java machine. The virtual machine is able to verify that the downloaded code contains no illegal memory references, viruses, or other errors. A verified program will not break any of the language or other constraints and may be safely executed. Many tests are done, at every level of complexity, from simple format checks to running a theorem prover. Extra type information is included in the byte codes so that the verifier can check that objects and data aren't illegally manipulated. When the tests are finished, the code is guaranteed not to do any of the following:
The verified bytes may then be executed by the interpreter. Each verified byte causes the interpreter to execute instructions. The code does not execute; instead, it causes certain actions to be performed by the interpreter, from a limited set of safe instructions that the interpreter has.
The verifier is the gatekeeper that lets byte codes perform actions only if they are safe. The verifier must be correct for safety to be ensured. Only Sun and Netscape are currently producing Java runtime environments; it won't be long before others join in. Sun will implement validation suites for runtimes, compilers, etc. to be sure that they're safe; in the meantime, this is another potential security hazard.
Sun is working on a just-in-time compiler to convert verified byte code into native machine code as it loads [7]. The compiler would generate binary code which the client machine which would run directly, replacing the interpreter. This would increase the speed at which a Java program is ready to run.
The Class Loader
There are three possible places from which a class may be loaded. In order of least to most protected, they are: the Internet, the firewall-guarded network on which your computer is located, and your computer. (Actually, you may implement even more realms than this, but these are standard.) You may implement any one of the following four security systems:
This protection is implemented in the java.lang.ClassLoader
class.
The class loader never allows a class from a less-protected realm to
replace a class from a more-protected realm. The local classes are defined
in a separate namespace from the loaded classes, so the loaded classes
may never supercede the local classes. In fact, classes in one realm
may not use or even see the methods of classes in other
realms unless they have been explicitly defined as public. Applets are also
protected from one another. They cannot access another applet's methods
without cooperation.
The Java Security Manager
The Security Manager restricts the ways an applet uses visible interfaces. This implements a good portion of the entire security model.
The Security Manager is completely customizable, though applets are not allowed to define Security Managers. A default Security Manager is provided as a template from Sun Microsystems. Each Java-enabled application fills in the template to meet security requirements for the application. The Java run time library is written so that all access requests are referred to the Security Manager.
The Security Manager has the following duties: