Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

It is highly unlikely that a method is built to deal with all possible runtime exceptions. Consequently, no method should ever catch RuntimeException. If a method catches RuntimeException, it may receive exceptions it was not designed to handle, such as NullPointerException. Many catch clauses simply log or ignore the enclosed exceptional condition, and normal execution resumes. Runtime exceptions indicate bugs in the program that should be fixed by the developer. They almost always lead to control flow vulnerabilities. Likewise, a method should never catch Exception or Throwable, because this implies catching RuntimeException (RuntimeException extends Exception which in turn extends Throwable).

Noncompliant Code Example

...

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 errors a null pointer exception condition if s is a null pointer. However, it also unintentionally catches other exceptional conditions exceptions that are unlikely to be handled properly, such as if an index is an ArrayIndexOutOfBoundsException resulting from an out of bounds index.

Compliant Solution

Instead of catching RuntimeException, a the program should be as specific as possible in catching exceptions as possible.

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;
}

This code only catches those exceptions that are intended to be caught. For example, a null pointer exception is caught whereas an index-out-of-bounds exception is not caught.

...

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. Consequently, the recovery process may not be tailored to the specific exception type that is thrown. AdditionallyFurthermore, unchecked exceptions under RuntimeException are also unintentionally caught whenever the top level Exception class is caught.

Code Block
bgColor#FFcccc
public class DivideException {
  public static void main(String[] args) {
    try {
      division(200, 5);
      division(200, 0); //divide 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

...

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
  catch (Exception e) { 
  System.out.println("Exception occurred :" + e.getMessage());
}	

...

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);   	
  }
}

DivideByZeroException is a custom exception type that extends Exception.

Exceptions

Wiki Markup
*EXC32-J-EX1*: A secure application must also abide by [EXC06-J. Do not allow exceptions to transmit sensitive information]. To follow this rule, an application might find it necessary to catch all exceptions at some top-level 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]. If exceptions need to be caught, it is better to catch {{Throwable}} instead of {{Exception}} \[[Roubtsov 03|AA. Java References#Roubtsov 03]\].

...