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