...
This noncompliant code example accepts a String
argument and attempts to determine whether it consists of a capital letter succeeded by lowercase letters. To handle anticipated corner cases, it detect a null string argument, the method wraps the code in a try-catch
block and reports any runtime exceptions that arise.
Code Block | ||
---|---|---|
| ||
boolean isCapitalized(String s) { try { if (s.equals("")) { return true; } String first = s.substring( 0, 1); String rest = s.substring( 1); return (first.equals (first.toUpperCase()) && rest.equals (rest.toLowerCase())); } catch (RuntimeException exception) { ExceptionReporter.report(exception); } return false; } |
This code reports a null pointer exception condition when s
is a null pointer, as intended by the programmer. However, it also unintentionally catches other exceptions that the programmer failed to anticipate, such as an ArrayIndexOutOfBoundsException
resulting from an out of bounds index. These other exceptions are reported, but are unlikely to be handled properly.
Compliant Solution
This compliant solution avoids Instead of catching RuntimeException
. Instead, it this compliant solution catches only the exceptions intended by the programmer; all . All other exceptions propagate up the call stack, to be handled by appropriate higher-level catch blocks.
Code Block | ||
---|---|---|
| ||
boolean isCapitalized(String s) { try { if (s.equals("")) { return true; } String first = s.substring(0, 1); String rest = s.substring(1); return (first.equals (first.toUpperCase()) && rest.equals (rest.toLowerCase())); } catch (NullPointerException exception) { ExceptionReporter.report (exception); } return false; } |
...
In this noncompliant code example, the original version of the division
method was declared to throw only ArithmeticException
. However, the caller catches a more general type (Exception
) to report arithmetic problems, rather than catching the specific exception type (ArithmeticException
). This practice is dangerousinsecure, because future changes to the method signature could add to the list of potential exceptions the caller must handle. In this example, a newer version of the division
method can potentially throw IOException
in addition to ArithmeticException
. However, the compiler cannot tell the caller's developer that he must provide a corresponding handler, because his existing code already catches IOException
as a result of catching Exception
. Consequently, the recovery process may be inappropriate for the specific exception type that is thrown. Furthermore, the developer has failed to anticipate that catching Exception
also catches unchecked exceptions; the developer has failed to anticipate this possibility.
Code Block | ||
---|---|---|
| ||
public class DivideException { public static void main(String[] args) { try { division(200, 5); division(200, 0); // Divide by zero } catch (Exception e) { System.out.println("Divide by zero exception : " + e.getMessage()); } } public static void division(int totalSum, int totalNumber) throws ArithmeticException, IOException { int average = totalSum / totalNumber; // Additional operations that may throw IOException... System.out.println("Average: " + average); } } |
...
EXC14-EX0: A catch block may catch all exceptions to process them before re-throwing them. For example:
...
, filtering sensitive information from exceptions before the call stack leaves a trust boundary. Refer to guideline ERR06-J. Do not allow exceptions to expose sensitive information, as well as CWE 7 and CWE 388).
In such cases, a catch block should catch Throwable
rather than Exception
or RuntimeException
.
Wiki Markup |
---|
*EXC14-EX1*: Task processing threads such as worker threads in a thread pool or the swingSwing event dispatch thread are permitted to catch {{RuntimeException}} when they call untrusted code through an abstraction such as {{Runnable}} \[[Goetz 2006 pg 161|AA. Bibliography#Goetz 06]\]. |
EXC14-EX2: Systems that require substantial fault tolerance or graceful degradation are permitted to catch and log general exceptions such as Throwable
at appropriate levels of abstraction. For example:
- A realtime real time control system that catches and logs all exceptions at the outermost layer, followed by warm-starting the system so that realtime real time control can continue. Such approaches are clearly justified when program termination would have safety-critical or mission-critical consequences.
- A system that catches all exceptions that propagate out of each major subsystem, logs the exceptions for later debugging, and subsequently shuts down the failing subsystem (perhaps replacing it with a much simpler, limited-functionality version) while continuing other services.
Risk Assessment
Catching RuntimeException
traps several types of exceptions not intended to be caught. This prevents may unintentionally trap other exception types and prevent them from being handled properly.
...
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
Related Guidelines
MITRE CWE: CWE ID 396 "Declaration of Catch for Generic Exception", CWE ID 7 "J2EE Misconfiguration: Missing Error Handling", CWE ID 537 "Information Leak Through Java Runtime Error Message", CWE ID 536 "Information Leak Through Servlet Runtime Error Message"
The Elements of Java Style: Rule 87: Do not silently absorb a run-time or error exception
Bibliography
Wiki Markup |
---|
\[[Doshi 2003|AA. Bibliography#Doshi 03]\] \[[JLS 2005|AA. Bibliography#JLS 05]\] [Chapter 11, Exceptions|http://java.sun.com/docs/books/jls/third_edition/html/exceptions.html] \[[J2SE 2011|AA. Bibliography#J2SE 11]\] Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking \[[MITRE 2009|AA. Bibliography#MITRE 09]\] [CWE ID 396|http://cwe.mitre.org/data/definitions/396.html] "Declaration of Catch for Generic Exception", [CWE ID 7|http://cwe.mitre.org/data/definitions/7.html] "J2EE Misconfiguration: Missing Error Handling", [CWE ID 537|http://cwe.mitre.org/data/definitions/537.html] "Information Leak Through Java Runtime Error Message", [CWE ID 536|http://cwe.mitre.org/data/definitions/536.html] "Information Leak Through Servlet Runtime Error Message" \[[Muller 2002|AA. Bibliography#Muller 02]\] \[[Rogue 2000|AA. Bibliography#Rogue 2000]\] Rule 87: Do not silently absorb a run-time or error exception \[[Schweisguth 2003|AA. Bibliography#Schweisguth 03]\] \[[Tutorials 2008|AA. Bibliography#tutorials 08]\] Exceptions|http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html] |
...