Java.next -- Four languages that represent the future of Java
Blogger Stuart Halloway has begun a series of posts on trends that point to the future of the Java platform. In his first post, he compares Clojure, Groovy, JRuby, and Scala -- four wildly different languages that nonetheless all play together in the JRE. Find out what unites these languages and what they can tell us about the future of Java-based development ...

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Twelve rules for developing more secure Java code

Writing security-conscious Java code can help you avoid security surprises

This article introduces 12 rules for writing security-critical Java code; 12 rules that all Java developers should abide by. If you are charged with managing a gaggle of Java developers, or if your business relies on the security of Java, make sure your developers follow these rules.

These rules haven't been sugar-coated for mass consumption. They get fairly technical and require broad knowledge of Java to understand. Though experienced Java developers will understand all the rules that follow, less experienced Java developers may have a bit of homework to do. Nevertheless, following these rules will make your Java code more secure.

We base these rules on the experience of many people who have generously discussed their experience in building secure Java code. We are particularly grateful to Andrew Appel, Dirk Balfanz, Drew Dean, and Dan Wallach, of the Secure Internet Programming Team at Princeton, for helping us understand these issues. Others who have contributed significantly to the behind-the-scenes thinking that went into these rules include David Hopwood, Li Gong, and Jim Roskind.

In creating these 12 rules, we've drawn from much experience in hunting down Java security bugs, and on advice and observations from people who write and review security-critical Java code for a living. Each rule is designed to eliminate an unexpected gotcha that you might face.

Of course, security is an elusive goal. Following these rules certainly won't provide any guarantee that your code is completely secure. It is easy to write insecure code that follows these rules. By following these goals, however, you will minimize or eliminate certain kinds of security attacks that you might not have thought of.

Think of these rules as a first step. If you are writing code that may be linked or run in conjunction with untrusted code, then you should definitely consider following these rules.

Every attempt has been made to keep the rules simple enough that you can treat them as a checklist to be followed in mechanical fashion. That way you can save your brainpower for other security issues.

Rule 1: Don't depend on initialization

Most Java developers think there is no way to allocate an object without running a constructor. But this isn't true: there are several ways to allocate noninitialized objects.

The easy way to protect yourself against this problem is to write your classes so that before any object does anything, it verifies that it has been initialized. You can do this as follows:

  • Make all variables private. If you want to allow outside code to access variables in an object, this should be done via get and set methods. (This keeps outside code from accessing noninitialized variables.) If you're following Rule 3, you'll make the get and set methods final.

  • Add a new private boolean variable, initialized, to each object.

  • Have each constructor set the initialized variable as its last action before returning.

  • Have each nonconstructor method verify that initialized is true before doing anything. (Note that you may have to make exceptions to this rule for methods called by your constructors. If you do this, it's best to make the constructors call only private methods.)

    If your class has a static initializer, you will need to do the same thing at the class level. Specifically, for any class that has a static initializer, follow these steps:

    • Make all static variables private. If you want to allow outside code to access static variables in the class, this should be done via static get and set methods. This keeps outside code from accessing noninitialized static variables. If you're following Rule 3, you'll make the get and set methods final.

    • Add a new private static boolean variable, classInitialized, to the class.

    • Have the static constructor set the initialized variable as its last action before returning.

    • Before doing anything, have each static method and each constructor verify that classInitialized is true. (Note: constructors are required to call a constructor of the superclass, or another constructor of the same class, as their first action. So you will have to do that before you check classInitialized.)


Rule 2: Limit access to your classes, methods, and variables

Every class, method, and variable that is not private provides a potential entry point for an attacker. By default, everything should be private. Make something nonprivate only with good reason, and document that reason.

Rule 3: Make everything final (unless there's a good reason not to)



If a class or method isn't final, an attacker could try to extend it in a dangerous and unforeseen way. By default, everything should be final. Make something nonfinal only if there is a good reason, and document that reason.

You might think you can prevent an attacker from extending your class or its methods by declaring the class nonpublic. But if a class isn't public, it must be accessible from within the same package, and as Rule 4 (below) says, you shouldn't to rely on package scope access restrictions for security.

This advice may seem harsh. After all, the rule is asking you to give up extensibility, which is one of the main benefits of using an object-oriented language like Java. But when you're trying to provide security, extensibility is your enemy: it just provides an attacker with more ways to cause trouble.

Rule 4: Don't depend on package scope

Classes, methods, and variables that aren't explicitly labeled as public, private, or protected are accessible within the same package. Don't rely on this for security. Java classes aren't closed, so an attacker could introduce a new class into your package and use this new class to access the things you thought you were hiding. (A few packages, such as java.lang, are closed by default, and a few Java virtual machines (JVMs) let you close your own packages. But you're better off assuming packages aren't closed.)

Package scope makes a lot of sense from a software-engineering standpoint, since it prevents innocent, accidental access to things you want to hide. But don't depend on it for security.

Resources
  • McGraw, G. and Felten, E. (1998) Securing JavaGetting down to business with mobile code. John Wiley & Sons, New York. http://www.rstcorp.com/java-security.html
  • The Java Security Web site -- this splash page for Securing Java includes pointers to trade articles, a mailing list, and information about author events http://www.rstcorp.com/java-security.html
  • Splash page for Securing Java includes pointers to trade articles,
  • a mailing list, and information about author events
  • The Java Security Hotlist offers more than 100 links in 9 categories, covering every Java security Web site the authors have found http://www.rstcorp.com/javasecurity/links.html
  • Princeton's Secure Internet Programming Team -- the Princeton team's Website, featuring 2 FAQs and several technical articles http://www.cs.princeton.edu/sip
  • Java's Security Architect, Li Gong, has a Java Security Home Page that includes pointers to Li's security articles http://java.sun.com/people/gong/java/security.html
  • Javasoft's Java Security Page (straight from the horse's mouth; take with grain of salt) http://java.sun.com/security/
  • "Privileged code in JavaWhy the API changed from JDK1.2beta3 to JDK1.2beta4," a technical article by Gary McGraw and John Viega explaining the resoning behind the security API change and what could be improved http://www.developer.com/journal/techfocus/083198_jsecur.html