CWE-495, Private Data Structure Returned From A Public Method, is a method declared public that returns a reference to a private data structure. The caller can then modify it in unexpected ways. MITRE lists object oriented code in C, C++, Java and C#.
How it happens
Marking a field private only protects the field name. If a public method returns the object the field points to, the caller holds the same object.
// Vulnerable: callers get the real list
public class Roles {
private final List<String> granted = new ArrayList<>();
public List<String> getGranted() {
return granted;
}
}
// elsewhere:
roles.getGranted().add("admin"); // changes internal state
What an attacker gains
MITRE lists one consequence: the contents of the data structure can be modified from outside the intended scope, which affects integrity. The record has no observed CVEs.
How to find it
Static analysis can find some instances. In review, look at every getter that returns an array, list, map or buffer and ask whether the return is the actual internal object.
How to fix it
MITRE gives three options.
- Declare the method private if outside callers do not need it.
- Clone the member data and keep an unmodified version private to the object.
- Use public setter methods that govern how a private member can be modified.
public List<String> getGranted() {
return List.copyOf(granted); // a copy, not the original
}
public void grant(String role) {
validate(role);
granted.add(role); // changes go through checked code
}
Quick check
Does a final field stop the caller from changing the list?
No. Final stops reassigning the field, not changing the contents of the object it points to.