Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fixed to be normative. Have we listed all the necessary exceptions?

It is highly unlikely that a method is built to deal with Few, if any, methods are capable of handling all possible runtime exceptions. Consequently, no method should ever are forbidden to catch RuntimeException. If When a method catches RuntimeException, it may receive exceptions it was not designed to handleunanticipated by the designer, such as NullPointerException. Many catch clauses simply log or ignore the enclosed exceptional condition, and attempt to resume normal execution resumes; this practice often violates guideline EXC00-J. Do not suppress or ignore checked exceptions. Runtime exceptions often indicate bugs in the program that should be fixed by the developer. They almost always lead to , and often cause control flow vulnerabilities. Likewise, a method should never Methods are also forbidden to catch Exception or Throwable, because this implies catching RuntimeException (; RuntimeException extends Exception which in turn extends Throwable).

Noncompliant Code Example

This noncompliant code example takes accepts a String argument and returns true if attempts to determine whether it consists of a capital letter succeeded by lowercase letters. To handle anticipated corner cases, it merely wraps the code in a try-catch block and reports any runtime exceptions that may arise.

Code Block
bgColor#ffcccc
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 if when s is a null pointer, as intended by the programmer. However, it also unintentionally catches other exceptions that are unlikely to be handled properlythe 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

Instead of This compliant solution avoids catching RuntimeException. Instead, the program should be as specific as possible in catching exceptionsit catches only the exceptions intended by the programmer; all other exceptions propagate up the call stack, to be handled by appropriate higher-level catch blocks.

Code Block
bgColor#ccccff
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;
}

...

Noncompliant Code Example

This In this noncompliant code example handles a divide by zero exception initially. Instead of the specific exception type ArithmeticException, a more generic type Exception is caught. This is dangerous as any future exception declaration updates to the method signature (such as, addition of IOException) may no longer require the developer to provide a corresponding handler, 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 dangerous, 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 not be tailored to inappropriate for the specific exception type that is thrown. Furthermore, catching Exception also catches unchecked exceptions under RuntimeException are also unintentionally caught whenever the top level Exception class is caught; the developer has failed to anticipate this possibility.

Code Block
bgColor#FFcccc
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);
  }
}

Noncompliant Code Example

This noncompliant code example improves attempts improvement by catching a specific divide-by-zero exception but fails on the premise that it unscrupulously accepts other undesirable runtime exceptions, by catching Exceptionspecifically catching ArithmeticException. However, it continues to catch Exception, and consequently catches both unanticipated checked exceptions and also unanticipated runtime exceptions.

Code Block
bgColor#FFcccc
try {
  division(200,5);
  division(200,0); // Divide by zero        
} catch (ArithmeticException ae) { 
  throw new DivideByZeroException(); 
} catch (Exception e) { // DivideByZeroException extends Exception so is checked
  System.out.println("Exception occurred :" + e.getMessage());
}	

Compliant Solution

To be compliant, catch specific exception types especially when the types differ significantly. Here, ArithmeticException and IOException have been unbundled because they fall under very diverse categoriesThis compliant solution catches only the specific anticipated exceptions (ArithmeticException and IOException). All other exceptions are permitted to propagate up the call stack.

Code Block
bgColor#ccccff
import java.io.IOException;

public class DivideException {
  public static void main(String[] args) {
    try {
      division(200,5);
      division(200,0); // Divide by zero        
    } catch (ArithmeticException ae) { 
      throw new DivideByZeroException();  // DivideByZeroException extends Exception so is checked 
    } catch (IOException ie) { 
      System.out.println("I/O Exception occurred :" + ie.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);   	
  }
}

Note that DivideByZeroException is a custom exception type that extends Exception.

Exceptions

Wiki Markup
*EXC14-EX1*: A secureSecure application must also abideconform byto guideline [EXC06-J. Do not allow exceptions to expose sensitive information]. To follow this guidelineConsequently, an application mightmay findbe it necessaryrequired to catch _all_ exceptions at some top-appropriate level of abstraction to sanitize (or suppress) them. This is also summarized in the CWE entries, [CWE 7|http://cwe.mitre.org/data/definitions/7.html] and [CWE 388|http://cwe.mitre.org/data/definitions/388.html]. IfIn exceptions need to be caughtsuch cases, it is better to catchprefer catching {{Throwable}} insteadrather ofthan {{Exception}} \[[Roubtsov 2003|AA. Bibliography#Roubtsov 03]\].

Wiki Markup
*EXC14-EX2*: Task processing threads such as worker threads in a thread pool or the swing event dispatch thread are allowedpermitted to catch {{RuntimeException}} when they call untrusted code through an abstraction such as {{Runnable}} \[[Goetz 2006 pg 161|AA. Bibliography#Goetz 06]\]. 

Risk Assessment

Catching RuntimeException traps several types of exceptions not intended to be caught. This prevents them from being handled properly.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

EXC14-J

low

likely

medium

P6

L2

Automated Detection

TODOAutomated detection of code that catches RuntimeException, Exception, or Throwable is trivial. Sound automated determination of whether such code complies with the exceptions to this guideline is infeasible. Heuristic techniques may be helpful.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

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]
\[[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"
\[[SchweisguthMuller 20032002|AA. Bibliography#SchweisguthBibliography#Muller 0302]\]
\[[JLSRogue 20052000|AA. Bibliography#JLSBibliography#Rogue 052000]\] Rule 87: Do not silently absorb a run-time or [Chapter 11, Exceptions|http://java.sun.com/docs/books/jls/third_edition/html/exceptions.htmlerror 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]
\[[Doshi 2003|AA. Bibliography#Doshi 03]\]
\[[Muller 2002|AA. Bibliography#Muller 02]\]
\[[Rogue 2000|AA. Bibliography#Rogue 2000]\] Rule 87: Do not silently absorb a run-time or error exception

...

EXC13-J. Throw specific exceptions rather than the more general RuntimeException or Exception      06. Exceptional Behavior (EXC)      EXC15-J. Do not catch NullPointerException