Versions Compared

Key

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

Recall that immutability offers several benefits such as thread-safety, prevention against inadvertent modification of fields and malicious tampering. Class invariants and state are always consistent with the requirements and no defensive copying is necessary. However, sometimes it is not possible to make sensitive classes immutable. Fortunately, there is a mechanism that allows code to expose mutable classes to untrusted code by granting read-only access. This is largely achieved through Immutability of fields prevents inadvertent modification as well as malicious tampering so that defensive copying while accepting input or returning values is unnecessary. However, some sensitive classes cannot be immutable. Fortunately, read-only access to mutable classes can be granted to untrusted code using unmodifiable wrappers. For example, in the Collection classes include a set of wrappers that allow clients to observe an unmodifiable view of the particular a Collection object.

Noncompliant Code Example

This noncompliant code example consists of class Modifiable Mutable, which allows the internal ArrayList array object to be modified. An untrusted invoker may call the mutator method listIt() and violate the object's immutability property. :

Code Block
bgColor#ffcccc
lang#FFccccjava

class ModifiableMutable {	
    private List<Integer>int[] listarray = new ArrayList<Integer>()int[10];

    public voidint[] listItgetArray() {
    addSomething(list);
    // ...return array;
    }

  private  public void addSomethingsetArray(Collection<Integer>int[] collectioni) {
         collection.add(1); 
array = i;
    }
}

Compliant Solution

This compliant solution recommends an unmodifiable wrapper to shield the mutator method(s) and provide an unmodifiable view to the caller. Internally, the unmodifiable Collection's mutator methods are designed to throw an UnsupportedOperationException in such events.

Code Block
bgColor#ccccff
// ...
publicprivate voidMutable listIt() {
  addSomething(Collections.unmodifiableCollection(list));
  // ...
}

private void addSomething(Collection<Integer> collection) {
  collection.add(1); // throws java.lang.UnsupportedOperationException
} 
mutable = new Mutable();
public Mutable getMutable() {return mutable;}

An untrusted invoker may call the mutator method setArray() and violate the object's immutability property. Invoking the getter method getArray() also allows modification of the private internal state of the class. This class also violates OBJ05-J. Do not return references to private mutable class membersIt should be noted that objects present within the Collection may not be thread-safe, making them mutable in multithreaded contexts. Consider for example, an ArrayList of ArrayLists wherein the contained ArrayList is still susceptible to modification.

Noncompliant Code Example

This noncompliant code example shows an interface MutableInterface which declares an accessor and a mutator method. This class does not expose an unmodifiable view to implementing clients.extends the Mutable class with a MutableProtector subclass: 

Code Block
bgColor#FFcccc#ffcccc
langjava
class MutableProtector extends Mutable {
  @Override
interface MutableInterface {
  public int[] getArray(); {
 // accessor
  void setArray(int[] i); //mutator
}

class SensitiveMutable implements MutableInterface {
  int[] arrayreturn super.getArray().clone();
  }
}
// ...
private Mutable mutable = new int[10]; MutableProtector();
// mutableMay array

be safely publicinvoked int[] getArray() {
    return array.clone(); 
  }

  public void setArray(int[] i) {
    array = i;
  }
}
by untrusted caller having read ability
public Mutable getMutable() {return mutable;} 

In this class, invoking the getter method getArray() does not allow modification of the private internal state of the class, in accordance with OBJ05-J. Do not return references to private mutable class members. However, an untrusted invoker may call the method setArray() and modify the Mutable object.

Compliant Solution

In general, sensitive classes can be transformed into safe-view objects by implementing providing appropriate wrappers for all the methods defined by the core interface, including the mutator methods. In this case, the difference is that the mutators need to The wrappers for the mutator methods must throw an UnsupportedOperationException so that clients cannot carry out perform operations that affect the immutability property of the object.

This compliant solution constructs an UnmodifiableSensitiveMutable by extending the class SensitiveMutable. An interface UnmodifiableInterface consists of the method unmodifiableView() which accepts a SensitiveMutable object as the sole parameter. It returns an equivalent object that is a subtype of the same class, and which is unmodifiable. An exception is thrown if the caller attempts to use the mutator method on the returned object. This object can be passed to untrusted code as required.adds a setArray() method that overrides the Mutable.setArray() method and prevents mutation of the Mutable object:

Code Block
bgColor#ccccff
langjava
class MutableProtector
interface UnmodifiableInterface {
  SensitiveMutable unmodifiableView(SensitiveMutable sm);
}

class UnmodifiableSensitiveMutable extends SensitiveMutableMutable  {
  int[] array = new int[10];

@Override
  public void setArray(int[] igetArray() {
    throw new UnsupportedOperationExceptionreturn super.getArray().clone();
  }
} 

class UnmodifiableWrapper extends UnmodifiableSensitiveMutable implements UnmodifiableInterface { @Override
  public SensitiveMutablevoid unmodifiableViewsetArray(SensitiveMutableint[] smi) { 
    returnthrow new UnmodifiableWrapperUnsupportedOperationException(); // subtype of SensitiveMutable
  }
}

class Invoker {
  public static void main(String[] args) {
    UnmodifiableWrapper uw = new UnmodifiableWrapper();
    SensitiveMutable s = uw.unmodifiableView(sm);
    s.setArray(new int[10]); // throws UnsupportedOperationException unlike s.getArray()    
  }
}

...

// ...
private Mutable mutable = new MutableProtector();
// May be safely invoked by untrusted caller having read ability
public Mutable getMutable() {return mutable; } 

The MutableProtector wrapper class overrides the getArray() method and clones the array. Although the calling code gets a copy of the mutable object's array, the original array remains unchanged and inaccessible. The overriding setArray() method throws an exception if the caller attempts to use this method on the returned object. This object can be passed to untrusted code when read access to the data is permissible.

Applicability

Failure to provide an unmodifiable, safe - view of a sensitive mutable object to untrusted code can lead to malicious tampering and corruption of the object.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

SEC14-J

medium

probable

high

P4

L3

Automated Detection

Tool

...

Version

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

Bibliography

Wiki Markup
\[[Tutorials 2008|AA. Bibliography#Tutorials 08]\] [Unmodifiable Wrappers|http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html]

CheckerDescription

Bibliography


...

Image Added Image Added Image AddedSEC13-J. Do not allow unauthorized construction of classes in inaccessible packages      02. Platform Security (SEC)      SEC15-J. Prefer using SSLSockets over Sockets for secure data exchange