Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2021.1

Lack of concern about leaving objects in an inconsistent state Objects in general should—and security-critical objects must—be maintained in a consistent state even when exceptional conditions arise may leave them vulnerable. Usual Common techniques for avoiding this scenario include:maintaining object consistency include

  • Input validation (on method arguments, for example, method parameters)
  • Reordering the logic so that the code capable of resulting code that can result in the exceptional condition , executes before the code that modifies the object executesobject is modified
  • Using rollbacks in the event of failureThrough the use of rollbacks, upon intercepting a failure notification
  • Performing required operations on a temporary copy of the object and committing changes to the original object , only after their successful completion
  • Avoiding the need to modify the object at all

Noncompliant Code Example

This noncompliant code example shows a Dimensions class that contains three internal attributes, : the length, width, and height of a rectangular box. The getVolumePackage() method is designed to return the total volume required to hold the box , after accounting for packaging material, which further adds 2 units to the dimensions of each side. Non positive Nonpositive values of the dimensions of the box (exclusive of packaging material) are rejected during the input validation. No dimension can be larger than 10. Also, the weight of the object is passed in as an argument and cannot be more than 20 units. Consider the case where

If the weight is more than 20 units (21 units, here). This it causes an IllegalArgumentException, which is intercepted by the custom error reporter. While Although the logic restores the object's original state in the absence of this exception, it omits doing the same from within the catch block. This violates the object's invariants such that when getVolumePackage() is called for the second time, it produces the rollback code fails to execute in the event of an exception. Consequently, subsequent invocations of getVolumePackage() produce incorrect results.

Code Block
bgColor#FFcccc

class Dimensions {
  private int length;
  private int width;
  private int height;
  static public final int PADDING = 2;
  static public final int MAX_DIMENSION = 10;

  public Dimensions(int length, int width, int height) {
    this.length = length;
    this.width = width;
    this.height = height;
  }

  protected int getVolumePackage(int weight) {
    length += 2PADDING;
    width  += 2PADDING;
    height += 2PADDING;
    try {
      if (length <= 2PADDING || width <= 2PADDING || height <= 2 PADDING ||
        length > MAX_DIMENSION + PADDING || width > MAX_DIMENSION + PADDING ||
        height > MAX_DIMENSION + PADDING || weight <= 0 || weight > 20) {
        throw new IllegalArgumentException();
	
      }

      int volume = length * width * height; // 12 * 12 * 12 = 1728
        length -=2 PADDING; width -= 2PADDING; height -= 2PADDING; // Revert back
        return volume;
      } catch (Throwable t) { 
        MyExceptionReporter mer = new MyExceptionReporter();
        mer.report(t); // Sanitize 
        return -1; // Non-positive error code
      }	
  }

  public static void main(String[] args) {
    Dimensions d = new Dimensions(108, 108, 108);
    System.out.println(d.getVolumePackage(21)); // Prints -1 (error)
    System.out.println(d.getVolumePackage(19));
    // Prints 1728 2744(12x12x12) instead of 1000 1728(10x10x10)
  }
}

Compliant Solution

The catch clause is permitted by exception ERR08-J-EX0 in ERR08-J. Do not catch NullPointerException or any of its ancestors because it serves as a general filter passing exceptions to the MyExceptionReporter class, which is dedicated to safely reporting exceptions as recommended by ERR00-J. Do not suppress or ignore checked exceptions. Although this code only throws IllegalArgumentException, the catch clause is general enough to handle any exception in case the try block should be modified to throw other exceptions.

Compliant Solution (Rollback)

This compliant solution replaces the catch block in the getVolumePackage() method with code that restores prior object state in the event of an exception:To be compliant, restore prior object state on exceptional conditions.

Code Block
bgColor#ccccff

  // ...

  } catch (Throwable t) {
  
  MyExceptionReporter mer = new MyExceptionReporter();
    mer.report(t); // Sanitize
 
   length -=2 PADDING; width -= 2PADDING; height -= 2PADDING; // Revert
  back
  return -1;
  }	

Compliant Solution

...

(finally Clause)

This compliant solution uses a finally clause to perform rollback, guaranteeing that rollback occurs whether or not an error occurs:

Code Block
bgColor#ccccff
protected int getVolumePackage(int weight) {
  length += PADDING;
  width  += PADDING;
  height += PADDING;
  try {
    if (length <= PADDING || width <= PADDING || height <= PADDING ||
      length > MAX_DIMENSION + PADDING || 
      width > MAX_DIMENSION + PADDING || 
      height > MAX_DIMENSION + PADDING || 
      weight <= 0 || weight > 20) {
      throw new IllegalArgumentException();
    }

    int volume = length * width * height;
    return volume;
  } catch (Throwable t) {
    MyExceptionReporter mer = new MyExceptionReporter();
    mer.report(t); // Sanitize
    return -1; // Non-positive error code
  } finally {
    // Revert
    length -= PADDING; width -= PADDING; height -= PADDING; 
  }
}

Compliant Solution (Input Validation)

This compliant solution improves on the previous solution by performing A more preferable way is to perform input validation before modifying the state of the object. Note that the try block contains only those statements that could throw the exception; all others have been moved outside the try block.

Code Block
bgColor#ccccff

protected int getVolumePackage(int weight) {
  try {
    if (length <= 0 || width <= 0 || height <= 0 ||
        length > MAX_DIMENSION || width > MAX_DIMENSION || height > MAX_DIMENSION ||
        weight <= 0 || weight > 20) {
      throw new IllegalArgumentException(); // Validate first
    }
  } catch (Throwable t) { MyExceptionReporter lengthmer += 2;
    width = new MyExceptionReporter();
    mer.report(t); // Sanitize
    return -1;
  }

  length += 2PADDING;
  width  += PADDING;
  height += 2PADDING;

    int volume = length * width * height;
    length -=2 PADDING; width -= 2PADDING; height -= PADDING;
  return volume;
}

Compliant Solution (Unmodified Object)

This compliant solution avoids the need to modify the object. The object's state cannot be made inconsistent, and rollback is consequently unnecessary. This approach is preferred to solutions that modify the object but may be infeasible for complex code.

Code Block
bgColor#ccccff
protected int getVolumePackage(int weight) {
  try {
    if (length <= 0 || width <= 0 || height <= 0 ||
        length > MAX_DIMENSION || width > MAX_DIMENSION ||
        height > MAX_DIMENSION || weight <= 0 || weight > 20) {
      throw new IllegalArgumentException(); // Validate first
    } 2;
    return volume;
  } catch (Throwable t) { 
    MyExceptionReporter mer = new MyExceptionReporter();
    mer.report(t); // Sanitize 
    return -1;
  }		

  int volume = (length + PADDING) * (width + PADDING) *
               (height + PADDING);
  return volume;
}

Risk Assessment

Failing Failure to restore prior object state on method failure can leave the object in an inconsistent state and can violate required state invariants.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXC07

ERR03-J

low

Low

probable

Probable

high

High

P2

L3

Automated Detection

...

ToolVersionCheckerDescription
Parasoft Jtest

Include Page
Parasoft_V
Parasoft_V

CERT.ERR03.REVOBJRestore prior object state on method failure

Related Vulnerabilities

CVE-2008-0002

References

Wiki Markup
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 64: Strive for failure atomicity

describes a vulnerability in several versions of Apache Tomcat. If an exception occurs during parameter processing, the program can be left in the context of the wrong request, which might allow remote attackers to obtain sensitive information. An exception can be triggered by disconnecting from Tomcat during this processing.

Related Guidelines

MITRE CWE

CWE-460, Improper Cleanup on Thrown Exception

Bibliography

[Bloch 2008]

Item 64, "Strive for Failure Atomicity"


...

Image Added Image Added Image AddedEXC06-J. Do not let code throw undeclared checked exceptions      13. Exceptional Behavior (EXC)      EXC03-J. Use a logging API to log critical security exceptions