Skip to content

VNX-495: Private Data Structure Returned From A Public Method

A public Java method that returns an array type returns a private array field itself (return field; or return this.field;), so the caller receives a reference to the object's internal state and can change its elements. final on the field does not help: it fixes the reference, not the contents. Reported at the return statement. Not reported: a defensive copy (field.clone(), Arrays.copyOf, System.arraycopy into a new array, List.of/unmodifiableList), a private field initialised to an empty array (new T[0], {}), which cannot be changed, a local variable or method parameter that shadows the field, non-public methods, public fields (VNX-493 judges those), collections, and the pattern in comments or string literals.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-495
Severity Medium
SARIF level warning
Kind sast
Languages Java
CWE CWE-495
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags private-array defensive-copy encapsulation cwe-495
Source internal/sast/rules/vnx-495.rego

Overview

VNX-495 maps to CWE-495: Private Data Structure Returned From A Public Method. It reports public methods that hand out a private array field instead of a copy. VNX-375, the general mutable-return rule, leaves these lines to this rule and reports collections, dates and the other mutable fields.

Why This Matters

Arrays are mutable and returned by reference. A getter that returns roles lets the caller write getRoles()[0] = "admin" and change the object’s own state, bypassing every check the class performs on its setters. Marking the field final does not prevent this.

What Gets Flagged

public class KeyHolder {
    private byte[] secretKey;
    private final String[] roles;

    public byte[] getSecretKey() {
        return secretKey;                        // FLAGGED
    }

    public String[] getRoles() { return roles; } // FLAGGED
}

Not flagged: return secretKey.clone();, return Arrays.copyOf(roles, roles.length);, returning a private static final String[] EMPTY = new String[0];, and non-public methods.

Remediation

  1. Return a copy: return secretKey.clone(); or Arrays.copyOf(...).
  2. Return an unmodifiable view such as List.of(roles) or Collections.unmodifiableList(...).
  3. For secrets, avoid returning them at all; expose the operation (sign, verify) instead.

References

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-495
// nosec vnx-495

Or record an ignore rule: vulnetix ignore add --rule vnx-495 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-495.rego, cli/internal/sast/docs/vnx-495.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.