HostedDB - Dedicated UNIX Servers

-->
Internet Security Professional Reference:Java Security
Previous Table of Contents Next


Security

In addition to these performance, extensibility, and robust features, Java also provides a secure environment in which programs run on distributed systems. As mentioned previously Java enhances security in three main ways:

  By removing pointers and memory allocation at compile time as in C or C++, programmers are unable to “jump out” of their own area into restricted segments of the system to wreak havoc.
  The first stage in the interpreter is a bytecode verifier that tests to make sure that incoming code is proper Java code.
  The interpreter provides separate name spaces for each class that is uploaded, ensuring that accidental name references do not occur.

The Java language makes every attempt to assure that violation of security does not occur. Viruses, Trojan horses, and worms have added many headaches to a network administrator’s job. It is tough enough keeping out destructive programs when you can limit executables to deliberately stored files. The thought of automatically executing programs in HTML pages is an administrator’s nightmare and a system breaker’s dream. Java provides a multilevel system for ensuring that both intentional and unintentional errant programs are caught.

The first line of defense is always prevention. Java prevents many of the security problems in executables by removing the tools necessary—pointers. By providing all memory management, Java ensures that many of the tricks used to gain access to system resources are unavailable. Deferring allocation of memory layout until runtime prevents a programmer from deducing how memory will be used and forging pointers to restricted spaces.

Although the actual Java compiler checks for these problems, someone could create a compiler that will not. Java overcomes this problem by also checking the bytecodes at runtime. To ensure accuracy, Java puts the code through a theorem prover to be certain that the code does not do the following:

  Forge pointers
  Violate access restrictions
  Incorrectly access classes
  Overflow or underflow operand stack
  Use incorrect parameters of bytecode instructions
  Use illegal data conversions

After the code leaves the bytecode verifier, the interpreter can operate at near-native speeds, ensuring the program executes in a secure manner without compromising the system.

Java provides a host of security features to ensure that distributed programs to be executed on the system perform properly. The fact that dynamic and extensible applications may come from anywhere on the Internet is a breeding ground for attempts to break systems. If there is a system to break, someone will try. Protecting against this eventuality is of paramount importance, and the Java environment provides just the tools for doing so. The administrator always has the ultimate line of defense in restricting access to their machines from certain protocols—protocols that Java adheres to—but this also defeats the purpose of the Internet being a completely connected system where information flows freely in all directions.

From Class File to Execution

What happens when you finish writing your program and run it through the compiler? What happens when you hit a web page with an applet in it? How is it executed? You will find answers to these and other questions in this section.

The first step in the Java application life cycle is the compilation of code. Although this is fairly straightforward, there are several things a Java compiler does that are different from a C or C++ compiler. This is mainly in regard to the computation of numeric references. This chapter examines this difference, why it exists, and how it affects the runtime environment.

Once the Java code has been compiled and an end user downloads it, it must then be interpreted. For security reasons, the Java interpreter contains many safeguards against faulty code. Although it is possible that software you personally install may, at some point, crash your system, it is inexcusable for a code you encounter while surfing the Net to bring down the entire operation. Soon, no one would trust anyone’s code, and Java would become the scourge of the Internet. Java places many safety nets between the code and the system to protect against this inevitability, and this is a major portion of the runtime engine.

The Compilation of Code

The Java compiler acts just as any other compiler. It creates the machine code (essentially assembler code) for execution from a higher level language. This enables the programmer to write in an intelligible way what he or she wants to have done, while the compiler converts it into a format that a specific machine can run. The only difference between the Java compiler and other compilers is that the specific machine that would normally run the compiled code does not exist in Java. It is the JVM for which the Java compiler compiles the source code. There exist, however, several key differences from other languages in the way the compiler resolves references in code.

The Java compiler does not reduce the references in the program to numbers, nor does it create the memory layout the program will use. The reason for this implementation is portability, both in terms of neutrality and security. When a C compiler produces the object code, it can expect to be run on a specific hardware platform. Because the executable, even while running under an operating system, must be self-supporting in terms of addressing, the compiler can reduce the overhead by referring to exact memory offsets rather than to a symbolic reference that would then have to be looked up.


Previous Table of Contents Next