Returning references to internal object state (mutable or immutable fields and members, alike) can seriously compromise the security of an application because of the resulting sub par encapsulation properties and susceptibility to corruption of the class invariants inflicted by the clients of the code.
Noncompliant Code Example
This noncompliant piece of code defines a class that contains a Hashtable
instance field. Here, the hash table itself is designed to hold immutable data of sensitive nature (ssn
numbers). A getter method getValues()
is also provided to give the caller access to the hash table by returning a reference to it. This is dangerous since hostile code can surreptitiously view the contents of the object's private data. Not only that, it can also add, remove or modify the hash table entries at its will.
class ReturnRef { // internal state, may contain sensitive data Hashtable<Integer,String> ht = new Hashtable<Integer,String>(); private ReturnRef() { ht.put(1, "123-45-6666"); } private Hashtable<Integer,String> getValues(){ System.out.println(ht.get(1)); return ht; } public static void main(String[] args) { ReturnRef rr = new ReturnRef(); Hashtable<Integer,String> ht1 = rr.getValues(); // prints sensitive data 123-45-6666 ht1.remove(1); // untrusted caller can remove entries Hashtable<Integer,String> ht2 = rr.getValues(); // now prints null, original entry removed! } }
Compliant Solution
Do not provide a getter method like getValues()
that exposes private internal object state. This applies to both mutable as well as immutable instance fields and objects. The former can allow untrusted code to alter the state of the object while the latter can leak private information by breaking the encapsulation property.
If some internal object contains immutable data that is not of sensitive nature, create and return its shallow copy so that the caller cannot modify the originally referenced data. This solution highlights how a shallow copy of the internal hash table can be created and returned. Ergo, attempts to modify the original hash table run into a dry stretch.
private Hashtable<Integer,String> getValues(){ System.out.println(ht.get(1)); return (Hashtable<Integer,String>)ht.clone(); // shallow copy } public static void main(String[] args) { ReturnRef rr = new ReturnRef(); Hashtable<Integer,String> ht1 = rr.getValues(); // prints non sensitive data ht1.remove(1); // untrusted caller can remove entries only from the copy Hashtable<Integer,String> ht2 = rr.getValues(); // prints non sensitive data }
At other times, a deep copy may be desirable. This condition applies to all objects whose state comprises mutable data. For instance, if the hash table contained references to mutable data such as a series of Date
objects, every one of those objects will have to be copied by using a copy constructor. For further details, refer to FIO31-J. Create a copy of mutable inputs and OBJ36-J. Provide mutable classes with a clone method. Note that the keys of a hash table need not be deep copied; shallow copying of the references suffices since a hash table's contract dictates that it cannot hold duplicate keys.
Risk Assessment
Returning references to internal object state (mutable or immutable) can render an application susceptible to information leakage and corrupt the object's state and invariants. Control flow may also be affected in dire cases.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
SEC37-J |
high |
probable |
medium |
P12 |
L1 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as OBJ07-CPP. Do not return references to private data
References
[[API 06]] method clone()
[[Security 06]]
[[Bloch 08]] Item 39: Make defensive copies when needed
[[MITRE 09]] CWE ID 375 "Passing Mutable Objects to an Untrusted Method"
OBJ36-J. Provide mutable classes with a clone method 06. Object Orientation (OBJ) 06. Object Orientation (OBJ)