HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 
Java & Security, by P.G. Ramachandram

There are many concerns surrounding the security of Java applets and applications downloaded from the Internet. But because Java developers placed a lot of importance on security from the start, Java is the preferred technology for use in networked environments. When Java's security features are implemented properly, Java programs are safe and can be downloaded to your computer without any security risk.

There are a number of ways to implement security in Java. Security features can be applied to applets running in browsers as well as to Java applications. This article discusses the features of the Security Manager class.

Java Security Manager
The Java Security Manager arbitrates access to many of the operating system features such as files, network sockets and printers. It provides fine-grained control over which operations can be performed by code running within the Java Virtual Machine (JVM). The relationship between the Security Manager and other components is illustrated in Figure 1.

Figure 1
Figure 1

The application code uses Java API methods to access the Security Manager, which in turn uses an access controller to implement the security policies. However, under special circumstances the Security Manager can bypass the access controller to implement security policies.

The role of the Security Manager is to grant access to each Java class based on the amount of trust the user has in that class. The Java program must get permission from the Security Manager before it can connect to a particular machine on the network or access the file system. Whenever a Java program performs a restricted operation, it checks with the Security Manager to determine if that operation can be performed. If access is denied, the program throws a SecurityException. Nothing inherent in the Security Manager requires security to be enforced as an all-or-nothing proposition for each class.

The Security Manager can be written so that only classes loaded from the CLASSPATH are prohibited from performing certain operations normally permitted to classes loaded from the file system. The Security Manager has powerful features that can enforce a very detailed complex policy if necessary.

The most significant difference in Java 1.2 is that it's much easier to implement fine-grained security policies. The Security Manager in versions prior to Java 1.2 relied on internal logic to determine what policies should be in effect. Changing the policy required changing the Security Manager itself. The Java 1.2 Security Manager uses an access controller to enforce its protections. A Security Manager isn't necessary for every Java application, and applications by default have no Security Manager. Plenty of Java implementations are available and they don't have a standard Security Manager implementation. The methods in the Security Manager can be broadly classified into the following groups:

  • Methods protecting file access: These methods protect the file system from the user classes.
  • Methods protecting network access: These methods check the security details about the sockets and other network aspects.
  • Methods protecting program threads: These methods protect the manipulation of threads by other classes.
  • Methods protecting the JVM: These methods protect the integrity of the JVM.
  • Methods protecting system resources: These methods protect the system resources, such as printers and system properties.
  • Methods protecting Java security aspects: These methods protect security aspects of Java itself.

SecurityManager and Applets
The classes that constitute the applet are generally loaded from the network and in general are considered untrusted (for the sake of simplicity signed applets are not discussed here). An applet cannot set the Security Manager, so it will have to live with the established security policy of the browser it's running on. The implementation of browser SecurityManager prevents applets loaded over the network from reading or writing files from the client file system. Applets aren't allowed to get direct access to the underlying computer. Some other restrictions associated with applets are:

  • Applets can only create network connections back to the originating host of the applet.
  • Classes loaded over the network can't load libraries or consist of native methods. (This doesn't say applets can't call native methods – only that native methods can't be part of the classes loaded over the network.)
  • Applets can't fork off new system processes or see system properties that would expose the username or working directories.
How to Create a Security Manager
The SecurityManager class itself isn't intended to be used directly in your Java program (each of the checks defaults to throwing a security exception), but instead is intended to be inherited and installed as the System Security Manager. The subclassed Security Manager can be used to implement the desired security policy. The Security Manager is an abstract class and you need to extend this class to create your own Security Manager. The code for creating your own Security Manager is shown in Listing 1.

The Security Manager class has more than 25 checkXXX() methods, and these methods can be overridden to grant or deny access to a user. No methods in the Security Manager class need to be overridden. By default the Security Manager class throws an exception to all implementations of checkXXX()method, meaning that access is denied. To grant access to a certain method you must override it. One thing you should keep in mind before overriding the methods is that the methods should return if access is granted; otherwise, the methods should throw a SecurityException.

The checkRead() and checkWrite() methods are being overwritten in the Security Manager in this program. These methods grant or deny access to a particular file in the file system. The Security Manager provides three versions of checkRead() and two versions of checkWrite(). The signature of the methods that check whether a program is allowed to read the given file is:

public void checkRead(FileDescriptor fd)
public void checkRead (String file)
public void checkRead(String file, Object context)
The signature of the methods that check whether a program is allowed to write the given file is:
public void checkWrite(FileDescriptor fd)
public void checkWrite(String file)
The methods that are overridden in the program are checkRead(String s) and checkWrite(String s) methods in the SecurityManager class. All the checkXXX() methods throw SecurityException. This exception is a subclass of RuntimeException so it doesn't need to be within a try/catch block. This utilizes the property of the Java language in which exception handling is free as long as no exceptions are thrown. It's up to the Java API to call the checkXXX() methods at the appropriate time so you don't have to call the methods explicitly before a file read or write operation.

Next we'll install the newly created SecurityManager in our JVM. The code for installing and testing "MySecurityManager.java" can be found in Listing 2.

The two methods in the System class used to work with the Security Manager are:

  1. Public static SecurityManager getSecurityManager(): Returns a reference to the currently installed Security Manager object (or null if no Security Manager is in place). This method can be used to test various security policies.
  2. Public static void setSecurityManager(SecurityManager sm): Sets the Security Manager for the object. It can be called only once and can't be removed once the Security Manager is installed. The Security Manager will be used by other classes that run in that particular virtual machine.
To execute and test the program:
  • Create a file called input.txt in the current directory and type some text in the file.
  • Compile "MyTest.java" and "MySecurityManager.java" and run the program. The contents of the file input.txt will be transferred to the file output.txt. The output of the program is:
    Successfully opened the files for read/write
    Successfully performed the read/write operation
  • Change the value of the flag passed to the constructor of MySecurityManager in MyTest.java.
  • Compile both Java files and run the program. The program throws an exception, indicating that the security policy we implemented doesn't allow the user to read the file in the JVM that we're running the program on. The output of the program if the flag is set to false is:
    Exception in thread "main" java.lang.SecurityException: checkRead
    at MySecurityManager.checkRead(MySecurityManager.java:14)
    at java.io.FileInputStream.<init>(FileInputStream.java:65)
    at java.io.FileReader.<init>(FileReader.java:35)
    at MyTest.testFunc(MyTest.java, Compiled Code)
    at MyTest.main(MyTest.java:20)

Conclusion
The publicity given to the security holes in various widely used software applications put increased pressure on developers and companies. Both are realizing the importance of implementing tight security policies in their applications. Java security has undergone a lot of changes in each version of the programming language.

This article provides an overview of the Security Manager class in Java 1.2. The listings show an implementation of a Security Manager that grants or denies access to files in the file system. Having a basic understanding of the Security Manager will help you create the complex security policies required by applications to prevent misuse.

References
Java tutorial: www.javasoft.com Oaks, S. (1998). Java Security. O'Reilly.

Author Bio
P.G. Ramachandran is a senior software engineer at Tivoli Systems, Indianapolis, Indiana. He can be contacted at: [email protected]

	


Listing 1

//CodeMySecurityManager.java
public class MySecurityManager extends SecurityManager
{
    private boolean flag;
    public MySecurityManager(boolean flag)
    {
        this.flag = flag;
    }

    // Override checkRead function
    public void checkRead (String s)
    {
        if(!flag)
        {
            throw new SecurityException("checkRead");
        }
    }

    // Override checkWrite function
    public void checkWrite (String s)
    {
        if(!flag)
        {
            throw new SecurityException("checkWrite");
        }
    }
}

Listing 2

// Code MyTest.java
import java.io.*;

public class MyTest
{

  public static void main (String[] args)
  {
    try
    {
      MySecurityManager secMgr = new MySecurityManager(true);
        // Set the security manager
      System.setSecurityManager(secMgr);
    }
    catch (SecurityException excp)
    {
      System.out.println("Can't Change the SecurityManager!");
    }
    // Construct an Object
    MyTest test = new MyTest();
    test.testFunc();

  }


  public void testFunc()
  {
    try
    {

      BufferedReader is = new BufferedReader(
                              new FileReader("input.txt"));
      DataOutputStream os = new DataOutputStream(
                                new FileOutputStream("out-      
                                               put.txt"));

      System.out.println("Successfully opened the files for     
                        read/write ");

      String readString;

      while ((readString = is.readLine()) != null)
      {
          os.writeBytes(readString);
          os.writeByte('\n');
      }
      System.out.println("Successfully performed the      
      read/write operation");
      is.close();
      os.close();
    }
    catch (IOException excp)
    {
      System.err.println("IOException.");
    }
  }

}

  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.