VNX-374: Passing Mutable Objects to an Untrusted Method
A public or protected Java method or constructor stores a mutable argument (an array, a mutable collection, Date, Calendar or StringBuilder) straight into a field instead of a copy.
| Field | Value |
|---|---|
| Rule ID | VNX-374 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Java |
| CWE | CWE-374 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | passing-mutable-objects cwe-374 |
| Source | internal/sast/rules/vnx-374.rego |
Overview
VNX-374 maps to CWE-374: Passing Mutable Objects to an Untrusted Method. It reports this.field = param; (or field = param; for a field declared in the file) inside a public or protected method or constructor, when param is declared in that signature as an array or as List, ArrayList, LinkedList, Map, HashMap, TreeMap, LinkedHashMap, Set, HashSet, TreeSet, LinkedHashSet, Collection, Deque, Queue, Date, Calendar or StringBuilder. Signatures that span several lines are followed.
Not reported: a defensive copy or view (new ArrayList<>(p), List.copyOf(p), p.clone(), Arrays.copyOf(p, n), new Date(p.getTime()), Collections.unmodifiable*), immutable parameter types (String, primitives, ImmutableList), private and package-private methods, a value derived from the parameter, JPA/document entities and JAXB-bound classes (@Entity, @Embeddable, @MappedSuperclass, @Document, @XmlRootElement, @XmlType), test sources and comments.
Why This Matters
When an object keeps the caller’s own list, array or date, the caller still holds a live reference to the object’s internal state. Anything the constructor or setter validated can be changed afterwards (a key array zeroed, an expiry date moved, an order line added after the total was checked) without going through the object’s methods.
What Gets Flagged
public KeyHolder(byte[] key, Date notAfter) {
this.key = key; // FLAGGED
this.notAfter = notAfter; // FLAGGED
}
public void setItems(List<LineItem> items) {
this.items = items; // FLAGGED
}
Not flagged: this.items = new ArrayList<>(items);, this.key = key.clone();, this.name = name; with a String parameter.
Remediation
- Store a copy:
new ArrayList<>(items),List.copyOf(items),key.clone(),new Date(d.getTime()). - Prefer immutable types for fields (
List.copyOf,java.time.Instantinstead ofDate). - If sharing the reference is intended, keep the method package-private or document the ownership transfer.
References
- CWE-374: Passing Mutable Objects to an Untrusted Method
- SEI CERT OBJ06-J: Defensively copy mutable inputs and mutable internal components
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-374
// nosec vnx-374
Or record an ignore rule: vulnetix ignore add --rule vnx-374 --reason "...". See Suppressing findings.