Java coding guidelines: 75 recommendations for reliable and secure programs (2014)
James A. Gosling
This set of Java™ Coding Guidelines, a follow-on to the earlier The CERT® Oracle® Secure Coding Standard for Java™, is invaluable. This book could almost be retitled Reliable Java™ Coding Guidelines. One of the things that has struck me over the years is the interplay between reliability and security. There are all sorts of explicit security tools—cryptography, authentication, and others—but most break-ins are exploitations of bugs: coding that was badly done or that was insufficiently defensive. Building a reliable system is, in many ways, equivalent to building a secure system. The work you do in reliability pays off in security, and vice versa.
This book highlights the fact that security is not a feature; it is an attitude toward taking due care at every point. It should be a continuous part of every software engineer’s design thought process. It is organized around a list of guidelines. The meat of the book is the subtlety behind them. For example, “Store passwords using a hash function” appears to be a very basic and obvious point, and yet there are regular news articles about major data breaches just because some software engineer wasn’t thinking. Getting it right is tricky: there are a lot of details for the devil to hide in. This book is full of excellent guidance for dealing with those details.
Java™ Coding Guidelines: 75 Recommendations for Reliable and Secure Programs provides specific advice to Java programmers. The application of these Java coding guidelines will lead to better systems that are more robust and more resistant to attack. These guidelines cover a wide range of products coded in Java for devices such as PCs, game players, mobile phones, tablets, home appliances, and automotive electronics.
Developers in any programming language should follow a set of guidelines to control the structures of their programs over and above what is specified by the programming language definition, and this is no less the case in Java.
Java programmers need more help than that provided by the Java Language Specification (JLS) [JLS 2013] to produce reliable and secure Java programs. Java contains language features and APIs that can easily be misused, and guidance is needed to avoid these pitfalls.
For a program to be reliable, it must work in all situations and in the face of all possible input. Inevitably, any nontrivial program will encounter a completely unexpected input or situation, and errors will occur. When such errors occur, it is important that the impact be limited, which is best achieved by localizing the error and dealing with it as soon as possible. Programmers can benefit from the experience of others in anticipating unusual input or programming situations and adopting a defensive style of programming.
Some of these guidelines may be deemed stylistic, but they are nonetheless important for readability and maintainability of the code. For Java, Oracle provides a set of code conventions [Conventions 2009] to help programmers produce a consistent programming style, and these conventions are widely adopted by Java programmers.
The CERT® Oracle® Secure Coding Standard for Java™
Java™ Coding Guidelines is written by the authors of The CERT® Oracle® Secure Coding Standard for Java™ [Long 2012]. That coding standard provides a set of rules for secure coding in the Java programming language. The goal of those rules is to eliminate insecure coding practices that can lead to exploitable vulnerabilities. The Secure Coding Standard establishes normative requirements for software systems. These software systems can then be evaluated for conformance to the coding standard, for example, by using the Source Code Analysis Laboratory (SCALe) [Seacord 2012]. However, there are poor Java coding practices that, despite not warranting inclusion in a secure coding standard for Java, can lead to unreliable or insecure programs. This book serves to document and warn against such coding practices.
Although not included in The CERT® Oracle® Secure Coding Standard for Java™, these guidelines should not be considered less important. Guidelines must be excluded from a coding standard when it is not possible to form a normative requirement. There are many reasons that a normative requirement cannot be formed. Perhaps the most common is that the rule depends on programmer intent. Such rules cannot be automatically enforced unless it is possible for the programmer’s intent to be specified, in which case a rule could require consistency between the code and the specified intent. Forming a normative requirement also requires that a violation of that requirement represent a defect in the code. Guidelines have been excluded from the coding standard (but included in this book) in cases where compliance with the guideline is always a good idea, but violating the guideline does not always result in an error. This distinction is made because a system cannot be cited for nonconformance without a specific defect. Consequently, coding rules must be very narrowly defined. Coding guidelines can often have a more far-reaching impact on security and reliability just because they can be more broadly defined.
Many of the guidelines refer to rules in The CERT® Oracle® Secure Coding Standard for Java™. These references are of the form “IDS01-J. Normalize strings before validating them,” where the first three letters of the reference identify the appropriate chapter of The CERT® Oracle®Secure Coding Standard for Java™. For example, IDS refers to Chapter 2, “Input Validation and Data Sanitization (IDS).”
The Secure Coding Standard for Java rules are also available on CERT’s secure coding wiki at www.securecoding.cert.org, where they continue to evolve. The CERT® Oracle® Secure Coding Standard for Java™ provides the definition of the rules for conformance testing purposes, but the wiki may contain additional information or insights not included in the book that may help you interpret the meaning of these rules.
Cross-references to other guidelines throughout this book are given simply by the number and title of the guideline.
Java™ Coding Guidelines focuses on the Java SE 7 Platform environment, and includes guidelines that address the issue of secure coding using the Java SE 7 API. The Java Language Specification: Java SE 7 Edition (the JLS) [JLS 2013] prescribes the behavior of the Java programming language and serves as the primary reference for the development of these guidelines.
Traditional language standards, such as those for C and C++, include undefined, unspecified, and implementation-defined behaviors that can lead to vulnerabilities when a programmer makes incorrect assumptions about the portability of these behaviors. By contrast, the JLS more completely specifies language behaviors, because Java is designed to be a cross-platform language. Even then, certain behaviors are left to the discretion of the implementer of the Java Virtual Machine (JVM) or the Java compiler. These guidelines identify such language peculiarities, suggest solutions to help implementers address the issues, and let programmers appreciate and understand the limitations of the language and navigate around them.
Focusing only on language issues does not translate to writing reliable and secure software. Design issues in Java APIs sometimes lead to their deprecation. At other times, the APIs or the relevant documentation may be interpreted incorrectly by the programming community. These guidelines identify such problematic APIs, and highlight their correct use. Examples of commonly used faulty design patterns and idioms are also included.
The Java language, its core and extension APIs, and the JVM provide several security features, such as the security manager and access controller, cryptography, automatic memory management, strong type checking, and bytecode verification. These features provide sufficient security for most applications, but their proper use is of paramount importance. These guidelines highlight the pitfalls and caveats associated with the security architecture, and stress its correct implementation. Adherence to these guidelines safeguards trusted programs from a plethora of exploitable security bugs that can cause denial of service, information leaks, erroneous computations, and privilege escalation.
Figure P–1 is a conceptual diagram of Oracle’s Java SE products.
Figure P–1. Conceptual diagram of Oracle’s Java SE products. (From Oracle Java SE Documentation, http://docs.oracle.com/javase/7/docs/. Copyright © 1995, 2010, Oracle and/or its affiliates. All rights reserved.)
These coding guidelines address security issues primarily applicable to the lang and util base libraries as well as for “other base libraries.” They avoid the inclusion of open bugs that have already been marked to be fixed or those that lack negative ramifications. A functional bug is included only if it is likely to occur with high frequency, causes considerable security or reliability concerns, or affects most Java technologies that rely on the core platform. These guidelines are not limited to security issues specific to the core API, but also include important reliability and security concerns pertaining to the standard extension APIs (javax package).
Demonstrating the full range of security features that Java offers requires studying interaction of code with other components and frameworks. Occasionally, the coding guidelines use examples from popular web and application frameworks such as Spring and Struts and technologies such as Java Server Pages (JSP) to highlight a security vulnerability that cannot be examined in isolation. Only when the standard API provides no option to mitigate a vulnerability are third-party libraries and solutions suggested.
Issues Not Addressed
A number of issues are not addressed by this secure coding standard.
These coding guidelines apply broadly to all platforms; concerns specific to only one Java-based platform are beyond the scope of these guidelines. For example, guidelines that are applicable to Android, Java Micro Edition (ME), or Java Enterprise Edition (EE) alone and not to Java Standard Edition (SE) are typically excluded. In Java SE, APIs that deal with the user interface (user interface toolkits) or the web interface for providing features such as sound, graphical rendering, user account access control, session management, authentication, and authorization are beyond the scope of these guidelines. Nevertheless, the guidelines discuss networked Java systems in light of the risks associated with improper input validation and injection flaws and suggest appropriate mitigation strategies. These guidelines assume that the functional specification of the product correctly identifies and prevents higher-level design and architectural vulnerabilities.
Coding style issues are subjective; it has proven impossible to develop a consensus on appropriate style guidelines. Consequently, Java™ Coding Guidelines generally avoids requiring enforcement of any particular coding style. Instead, we suggest that the user define style guidelines and apply those guidelines consistently. The easiest way to consistently apply a coding style is with the use of a code formatting tool. Many integrated development environments (IDEs) provide such capabilities.
Many of these guidelines are not amenable to automatic detection or correction. In some cases, tool vendors may choose to implement checkers to identify violations of these guidelines. As a federally funded research and development center (FFRDC), the Software Engineering Institute (SEI) is not in a position to recommend particular vendors or tools for this purpose.
In general, Java™ Coding Guidelines tries to avoid the inclusion of controversial guidelines that lack a broad consensus.
Java™ Coding Guidelines is primarily intended for developers of Java language programs. Although these guidelines focus on the Java SE 7 Platform environment, they should also be informative (although incomplete) for Java developers working with Java ME or Java EE and other versions of the Java language.
While primarily designed for building reliable and secure systems, these guidelines are also useful for achieving other quality attributes such as safety, dependability, robustness, availability, and maintainability.
These guidelines may also be used by
Developers of analyzer tools who wish to diagnose insecure or nonconforming Java language programs
Software-development managers, software acquirers, or other software-development and acquisition specialists to establish a proscriptive set of secure coding standards
Educators as a primary or secondary text for Java programming courses
Contents and Organization
Java™ Coding Guidelines consists of 75 guidelines organized around the following principles.
Chapter 1, “Security,” presents guidelines for ensuring the security of Java applications.
Chapter 2, “Defensive Programming,” contains guidelines for defensive programming so that the programmer can write code that protects itself from unexpected circumstances.
Chapter 3, “Reliability,” gives advice for improving the reliability and security of Java applications.
Chapter 4, “Program Understandability,” provides advice about making programs more readable and understandable.
Chapter 5, “Programmer Misconceptions,” exposes situations where Java language and programming concepts are often misunderstood.
Appendix A, “Android,” describes the applicability of the guidelines in this book to developing Java apps for the Android platform. The book also contains a glossary of common terms and a list of references.
The guidelines have a consistent structure. The title and the introductory paragraphs define the essence of the guideline. This is typically followed by one or more pairs of noncompliant code examples and corresponding compliant solutions. Each guideline concludes with an applicability section and bibliographical references specific to that guideline.