Versions Compared

Key

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

...

A TOCTOU inconsistency exists in this code sample. Since cookie is a mutable input, a malicious attacker may cause the cookie to expire between the initial check and the actual use.

Code Block
bgColor#FFcccc
import java.net.HttpCookie;

public final class MutableDemo {

  // java.net.HttpCookie is mutable
  public void UseMutableInput(HttpCookie cookie) {
    if (cookie == null) {
      throw new NullPointerException();
    }

    //check if cookie has expired
    if(cookie.hasExpired()) {
      //cookie is no longer valid, handle condition
    }

    doLogic(cookie);  //cookie may have expired since time of check resulting in an exception
  }
}

...

Wiki Markup
The problem is alleviated by creating a copy of the mutable input and using it to perform operations so that the original object is left unscathed. This can be realized by implementing the {{java.lang.Cloneable}} interface and declaring a {{public}} clone method or by using a copy constructor. Performing a manual copy of object state within the caller becomes necessary if the mutable class is declared as {{final}} (that is, it cannot provide an accessible copy method). (See \[[Guideline 2-1 Create a copy of mutable inputs and outputs|http://java.sun.com/security/seccodeguide.html]\].) Note that the input validation must follow after the creation of the copy.

Code Block
bgColor#ccccff

import java.net.HttpCookie;

public final class MutableDemo {

  // java.net.HttpCookie is mutable
  public void copyMutableInput(HttpCookie cookie) {
    if (cookie == null) {
      throw new NullPointerException();
    }

    // create copy
    cookie = (HttpCookie)cookie.clone();

    //check if cookie has expired
    if(cookie.hasExpired()) {
      //cookie is no longer valid, handle condition
    }

    doLogic(cookie);
  }
}

...

Code Block
bgColor#ccccff
  public void deepCopy(int[] ints, HttpCookie[] cookies) {
    if (ints == null || cookies == null) {
      throw new NullPointerException();
    }

    // shallow copy
    int[] intsCopy = ints.clone();

    // deep copy
    HttpCookie[] cookiesCopy = new HttpCookie[cookies.length];

    for (int i = 0; i < cookies.length; i++) {
      // manually create copy of each element in array
      cookiesCopy[i] = (HttpCookie)cookies[i].clone();
    }
 
    doLogic(intsCopy, cookiesCopy);
}

...