Versions Compared

Key

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

When System.exit() is invoked, all programs and threads running on the JVM terminate. This can result in denial-of-service attacks, for example, a web server can stop servicing users upon encountering an untimely call to System.exit() that is embedded in some JSP code.

Noncompliant Code Example

...

This compliant solution installs a custom security manager PasswordSecurityManager that overrides the checkExit() method defined in the SecurityManager class. This is necessary in cases where some clean up actions must be performed prior to allowing the exit. The default checkExit() method in the SecurityManager class does not offer this facility.In the overridden implementation, an internal flag is used to keep track of whether the exit is permitted or not. The method setExitAllowed() is used to set this flag. If the flag is not set (false), a SecurityException is thrown. The System.exit() call is not allowed to execute by catching the SecurityException in a try-catch block. After intercepting and performing mandatory clean-up operations, the setExitAllowed() method is invoked. As a result, the program exits gracefully.

Code Block
bgColor#ccccff
class PasswordSecurityManager extends SecurityManager {
  private boolean isExitAllowedFlag; 
  
  public PasswordSecurityManager(){
    super();
    isExitAllowedFlag = false;  
  }
 
  public boolean isExitAllowed(){
    return isExitAllowedFlag;	 
  }
 
  @Override public void checkExit(int status) {
    if(!isExitAllowed()) {
      throw new SecurityException();
    }
    super.checkExit(status);
  }
 
  public void setExitAllowed(boolean f) {
    isExitAllowedFlag = f; 	 
  }
}

public class InterceptExit {
  public static void main(String[] args) {
    PasswordSecurityManager secManager = new PasswordSecurityManager();
    System.setSecurityManager(secManager);
    try {
      // ...
      System.exit(1);  // Abrupt exit call
    } catch (Throwable x) {
      if (x instanceof SecurityException) {
        System.out.println("Intercepted System.exit()");
        // Log exception
      } else {
        // Forward to exception handler
      }
    }

    // ...
    secManager.setExitAllowed(true);  // Permit exit
    // System.exit() will work subsequently
    // ...
  }
}

In the overridden implementation, an internal flag is used to keep track of whether the exit is permitted or not. The method setExitAllowed() is used to set this flag. If the flag is not set (false), a SecurityException is thrown. The System.exit() call is not allowed to execute by catching the resulting SecurityException. After intercepting and performing mandatory clean-up operations, the setExitAllowed() method is invoked. As a result, the program exits gracefully.

Noncompliant Code Example

...