Book Review: The CERT Oracle Secure Coding Standard For Java
brothke writes "It has been a decade since Oracle started their unbreakable campaign touting the security robustness of their products. Aside from the fact that unbreakable only refers to the enterprise kernel; Oracle still can have significant security flaws. Even though Java supports very strong security controls including JAAS (Java Authentication and Authorization Services), it still requires a significant effort to code Java securely. With that The CERT Oracle Secure Coding Standard for Javais an invaluable guide that provides the reader with the strong coding guidelines and practices in order to reduce coding vulnerabilities that can lead to Java and Oracle exploits." Read on for the rest of Ben's review.
The CERT Oracle Secure Coding Standard for Java
author
Fred Long, Dhruv Mohindra, Robert Seacord, Dean Sutherland, David Svoboda
pages
744
publisher
Addison-Wesley Professional
rating
10/10
reviewer
Ben Rothke
ISBN
0321803957
summary
Definitive guide on the topic
The book is from CERT, and like other CERT books, provides both the depth and breadth necessary to gain mastery on the topic.
The first 100 pages of the book are available here. After reading it, you will be likely to want to see the next 650 pages.
This book provides a set of guidelines for secure programming in Java SE 6 and 7 environments. It is primarily targeted at software developers and computer security practitioners. While Java is inherently designed to be relatively secure as compared with other languages, it requires the developer to understand the security controls and language features thoroughly before he can implement them correctly. The book illustrates insecure coding practices and suggests corresponding safe alternatives to enable a developer to have an optimal blueprint.
Software developers are constantly under pressure to accommodate feature requests and have to strike a fine balance between enhancing delivery excellence and releasing a software product in consonance with deadlines. At the same time they routinely tackle technical challenges and often document their experience for the benefit of others. This book is one such effort, in that, several programmers and reviewers have contributed the contents. It encourages a developer to think beyond programming logic and enables him to produce clear, concise, maintainable and secure code – a mandatory requirement for today's dynamic software industry which is plagued by a spectrum of security threats and attrition's.
This book isn't for a Java beginner. The introductory chapter expects an intermediate or seasoned Java professional to identify the gamut of security vulnerabilities that frequently manifest in code and design. The chapter briefly explains injections attacks, unintended information disclosure, denial of service and issues involving concurrency and class loaders. Summary tables have been provided to assist the reader to easily locate representative secure coding rules for each category.
The examples presented primarily encompass the lang and util libraries of Java SE and also cover collections, concurrency, logging, management, reflection, regex, zip, I/O, JMX, JNI, math, serialization and JAXP libraries. No particular Java platform or technology has been favored; the set of rules is generic and independent of whether a mobile, enterprise, desktop or web application is being developed.
Notably, the layout enables the practitioner to pick up any chapter or rule at random without requiring him to read the preceding pages. Each rule has a short description of a unique problem and one or more non-compliant and compliant code examples. Risk assessment and references to other coding standards along with bibliography are also provided.
Unfortunately, the suggested tips for automatic detection of described problems aren't very practical because no automated bug detection tools have been vetted. Some rules also have a related vulnerabilities section that preys on weaknesses in commonplace software in context of the described problem.
Chapter 2 focuses on input validation and data sanitization. It highlights attacks such as SQL, XML, and OS injection and XML External Entity (XXE) and suggests corresponding mitigation techniques. It mentions but doesn't elaborate on web-based attacks such as cross-site scripting and CSRF, to avoid being too domain specific. The chapter advises developers to normalize strings, canonicalize and validate path names, refrain from logging unsanitized input, use appropriate internationalization and globalization APIs, avoid string encoding misgivings and other issues.
Chapters 3, 4 and 5 deal with declarations and class initialization, expressions, and numeric operations respectively. Dangers of auto-boxing, side-effects in assertions, integer overflow, and vagaries of floating point arithmetic are discussed at length.
The examples are short, to the point and intellectually challenging for the advanced reader. For example, one rule – don't use denormalized numbers dissects a vulnerability in Java 1.6 and earlier that allows an attacker to perform a denial of service attack by sending a crafted input to the JVM.
The book devotes a chapter to object-oriented programming and stresses on limiting extensibility of classes, encapsulating data, ensuring that code refactoring doesn't result in broken class hierarchies, using generics for fun and profit and so on.
Another chapter discusses Java methods, for example, one rule suggests that subclasses mustn't increase the accessibility of an overridden method. There is some useful information about using methods of Object class properly. This information is standard advice that can also be found in other books. This book offers all that and more. For example, one rule documents a convincing and exhaustive list of reasons why you shouldn't use finalizers.
The book also highlights misconstrued exception handling practices through examples akin to the shortcuts programmers invent, to save themselves from the trouble of having to handle exceptions. It explains why doing that can be insidious. Information disclosure arising from ill-conceived exception handling strategies is also discussed. Some may disagree with the advice on the pretext that exception handling when done the right way leads to unreadable code, however, the features presented from Java 7 convincingly offer a middle path. Further, when compliance with a certain rule is believed to be challenging and costly, the standard allows documented deviations and even lists valid exceptions for each rule.
Chapters 9, 10, 11, 12 and 13 are reserved for concurrency related issues. There are more than 30 rules in these chapters; the set could qualify as a handbook of concurrency issues and solutions. At a high level, the chapters cover visibility and atomicity, locking, thread class APIs, thread pools and thread safety in multi-threaded Java programs. The chapters don't assume that the reader has any familiarity with multi-threaded programming.
The next few chapters highlight input-output (I/O) risks such as working with shared directories, using files securely, closing resource handles properly, serialization and more. The book doesn't assume that the reader has a sophisticated background in serialization and builds from the basics. It cites examples of vulnerabilities that necessitate understanding the role of serialization.
A chapter on platform security follows, and is meant for advanced Java users. This chapter leads to another on runtime environment that cautions against signing code, granting permissions frivolously and permitting insecure deployment configurations. The final chapter captures miscellaneous rules that forbid hardcoding sensitive information, leaking memory, generating weak random numbers and writing insecure singletons among other topics.
Many other leading security standards delineate high-level measures that must be taken to ensure compliance but most fall short of prescribing the exact recipe to get there. This book fills that gap by approaching security from the ground-zero level upwards. However, it doesn't clearly specify to what extent the rules will help organizations meet the compliance goals proposed by other security standards. All the same, the eighteen crisp chapters of this book undeniably have the potential to help the software developer win the battle against software insecurity on his own terms.
For those using Java on Oracle and hoping to build secure applications, The CERT Oracle Secure Coding Standard for Javais a very useful resource that no programmer should be without.
Ben Rothkeis the author of Computer Security: 20 Things Every Employee Should Know.
You can purchase The CERT Oracle Secure Coding Standard for Java from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
The first 100 pages of the book are available here. After reading it, you will be likely to want to see the next 650 pages.
This book provides a set of guidelines for secure programming in Java SE 6 and 7 environments. It is primarily targeted at software developers and computer security practitioners. While Java is inherently designed to be relatively secure as compared with other languages, it requires the developer to understand the security controls and language features thoroughly before he can implement them correctly. The book illustrates insecure coding practices and suggests corresponding safe alternatives to enable a developer to have an optimal blueprint.
Software developers are constantly under pressure to accommodate feature requests and have to strike a fine balance between enhancing delivery excellence and releasing a software product in consonance with deadlines. At the same time they routinely tackle technical challenges and often document their experience for the benefit of others. This book is one such effort, in that, several programmers and reviewers have contributed the contents. It encourages a developer to think beyond programming logic and enables him to produce clear, concise, maintainable and secure code – a mandatory requirement for today's dynamic software industry which is plagued by a spectrum of security threats and attrition's.
This book isn't for a Java beginner. The introductory chapter expects an intermediate or seasoned Java professional to identify the gamut of security vulnerabilities that frequently manifest in code and design. The chapter briefly explains injections attacks, unintended information disclosure, denial of service and issues involving concurrency and class loaders. Summary tables have been provided to assist the reader to easily locate representative secure coding rules for each category.
The examples presented primarily encompass the lang and util libraries of Java SE and also cover collections, concurrency, logging, management, reflection, regex, zip, I/O, JMX, JNI, math, serialization and JAXP libraries. No particular Java platform or technology has been favored; the set of rules is generic and independent of whether a mobile, enterprise, desktop or web application is being developed.
Notably, the layout enables the practitioner to pick up any chapter or rule at random without requiring him to read the preceding pages. Each rule has a short description of a unique problem and one or more non-compliant and compliant code examples. Risk assessment and references to other coding standards along with bibliography are also provided.
Unfortunately, the suggested tips for automatic detection of described problems aren't very practical because no automated bug detection tools have been vetted. Some rules also have a related vulnerabilities section that preys on weaknesses in commonplace software in context of the described problem.
Chapter 2 focuses on input validation and data sanitization. It highlights attacks such as SQL, XML, and OS injection and XML External Entity (XXE) and suggests corresponding mitigation techniques. It mentions but doesn't elaborate on web-based attacks such as cross-site scripting and CSRF, to avoid being too domain specific. The chapter advises developers to normalize strings, canonicalize and validate path names, refrain from logging unsanitized input, use appropriate internationalization and globalization APIs, avoid string encoding misgivings and other issues.
Chapters 3, 4 and 5 deal with declarations and class initialization, expressions, and numeric operations respectively. Dangers of auto-boxing, side-effects in assertions, integer overflow, and vagaries of floating point arithmetic are discussed at length.
The examples are short, to the point and intellectually challenging for the advanced reader. For example, one rule – don't use denormalized numbers dissects a vulnerability in Java 1.6 and earlier that allows an attacker to perform a denial of service attack by sending a crafted input to the JVM.
The book devotes a chapter to object-oriented programming and stresses on limiting extensibility of classes, encapsulating data, ensuring that code refactoring doesn't result in broken class hierarchies, using generics for fun and profit and so on.
Another chapter discusses Java methods, for example, one rule suggests that subclasses mustn't increase the accessibility of an overridden method. There is some useful information about using methods of Object class properly. This information is standard advice that can also be found in other books. This book offers all that and more. For example, one rule documents a convincing and exhaustive list of reasons why you shouldn't use finalizers.
The book also highlights misconstrued exception handling practices through examples akin to the shortcuts programmers invent, to save themselves from the trouble of having to handle exceptions. It explains why doing that can be insidious. Information disclosure arising from ill-conceived exception handling strategies is also discussed. Some may disagree with the advice on the pretext that exception handling when done the right way leads to unreadable code, however, the features presented from Java 7 convincingly offer a middle path. Further, when compliance with a certain rule is believed to be challenging and costly, the standard allows documented deviations and even lists valid exceptions for each rule.
Chapters 9, 10, 11, 12 and 13 are reserved for concurrency related issues. There are more than 30 rules in these chapters; the set could qualify as a handbook of concurrency issues and solutions. At a high level, the chapters cover visibility and atomicity, locking, thread class APIs, thread pools and thread safety in multi-threaded Java programs. The chapters don't assume that the reader has any familiarity with multi-threaded programming.
The next few chapters highlight input-output (I/O) risks such as working with shared directories, using files securely, closing resource handles properly, serialization and more. The book doesn't assume that the reader has a sophisticated background in serialization and builds from the basics. It cites examples of vulnerabilities that necessitate understanding the role of serialization.
A chapter on platform security follows, and is meant for advanced Java users. This chapter leads to another on runtime environment that cautions against signing code, granting permissions frivolously and permitting insecure deployment configurations. The final chapter captures miscellaneous rules that forbid hardcoding sensitive information, leaking memory, generating weak random numbers and writing insecure singletons among other topics.
Many other leading security standards delineate high-level measures that must be taken to ensure compliance but most fall short of prescribing the exact recipe to get there. This book fills that gap by approaching security from the ground-zero level upwards. However, it doesn't clearly specify to what extent the rules will help organizations meet the compliance goals proposed by other security standards. All the same, the eighteen crisp chapters of this book undeniably have the potential to help the software developer win the battle against software insecurity on his own terms.
For those using Java on Oracle and hoping to build secure applications, The CERT Oracle Secure Coding Standard for Javais a very useful resource that no programmer should be without.
Ben Rothkeis the author of Computer Security: 20 Things Every Employee Should Know.
You can purchase The CERT Oracle Secure Coding Standard for Java from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
It seem they provide a decent set of good practices that should result in more manageable code overall, not just from security point of view, but one that is easier to maintain and better suitet to modern, multi-threaded, shared, virtualised environments where code is usually run...
Obligatory bash quote: http://bash.org/?946461
Those who are interested in this book might also be interested in High-Assurance Design (660 pages, Addison-Wesley). (See http://assuredbydesign.com/haa/) It has a foreword by Peter Neumann, and contains much of the same material as the book being reviewed, as well as many secure design patterns, social engineering patterns, and attack patterns. The book also covers the topic of software reliability - not just security. Disclosure: I wrote High-Assurance Design, as well as Prentice Hall and Sun Microsystem's book Advanced Java 2 Development For Enterprise Applications.
a fine balance between enhancing delivery excellence and releasing a software product in consonance with deadlines.
Can I get this translated into English, please? I try to avoid parsing marketroid and/or manager babble. ;)
Let me explain...no there is too much. Let me sum up.
I've read 1000-page technical books that had no filler (at least none that I could find). They just had a LOT of ground to cover. Sigh. How do you distinguish the books with mostly filler from the books that aren't? You gotta slog through the whole thing. Or you gotta trust that that review you're reading was done by someone who slogged through the whole thing.
Sounds like you want more of a tutorial in the style of K\&R, rather than a reference book like this.
Practice Kind Randomness and Beautiful Acts of Nonsense.
Doesn't anyone remember that when Java first came out that it was marketed as a secure alternative to C and C++? Proponents claimed that Java got the security model right, and that we could all just get down to solving the problems at hand, rather than having to worry about writing insecure code.
Agreed. Java did get some things right. When was the last time someone took advantage of a buffer overflow in a Java program? (I'm talking about the Java language here, not about vulnerabilities in particular implementations of Java.) The fact that it garbage-collects memory for you is not only convenient, but closes off a whole class of vulerabilities like double-free, that still plague C/C++ programmers.
On top of that, Java provides a standard API for concurrency...standard C and C++ didn't provide any threading model until this year.
And Java provides a framework allowing a program to run hostile code and still maintain control. C has no such capability; if your C program runs hostile code, game over, you're pwned. So I'd say Java did solve some of the biggest problems affecting C...buffer overflows and memory-allocation errors. I'd say that makes Java more secure than C. The problems outlined in the book can mostly be applied to C as well, though you'll have to go outside the standard to do them (eg for multithreaded code).
There are many reasons to use Java, but as this book clearly demonstrates, security is not one of them. The notion that a language automatically provides security is flawed, at best. The best a language can do is provide a mental model which encourages secure coding. The rest is on the programmer.
I'd say that no language provides security, as perfect security is an impossible dream...we can strive for it, and approach it, but never quite reach it. So I'd rather say that Java provides more security than C.
Practice Kind Randomness and Beautiful Acts of Nonsense.
Ruby on Rails just can't compete with Java, as much as the Rubyists claim it can
Wait, what Rubyists are claiming that?
I'm a Ruby programmer. I'm also a Java programmer and a .NET programmer (and quite a few others besides) so I have a broard perspective. I follow most of the Ruby movers-and-shakers on blogs and Twitter, and I don't think I've ever heard that claim. If anything, Rubyists look to Java as the natural step up from Ruby to meet enterprise needs -- even more so now JRuby is one of the most stable and usable Ruby implementations out there. Twitter built their platform on Ruby and then moved pieces to Java as needed. I don't think their approach is even remotely unique -- I've certainly done the same thing myself.
I think you're repeating sweeping generalisations out of your own (unfounded and biased) opinion and getting it totally wrong.
It's kinda twisted ain't it? It's now official: Java was the single biggest attack vector in 2010 and it's so far ahead of Flash (and JavaScript) that it's going the "win" the award for being the biggest desktop security hole in 2011 too.
And I'm a Java developer (and I did patch in february the remote DoS "2.2250738585072012e-308" bug). So don't see this as "Java bashing".
Honestly it's sad for a VM that doesn't allow buffer overflow/overrun to see all the myriad other holes that it's suffering from. It's a joke. A very, very, sad joke.
And one can't help pitty all the users who do not need Java and who caught malware due to Java holes in 2010/2011.
So "Oracle best security practices for Java", sure... But what's the point when the VM itself is full of holes?