Skip to content

VNX-1098: Data Element containing Pointer Item without Proper Copy Control Element

A C++ class whose destructor releases a raw pointer (delete, delete[], free) but which declares no copy constructor, so the implicit shallow copy leads to a double free (rule of three).

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-1098
Severity Low
SARIF level note
Kind sast
Languages C++
CWE CWE-1098
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 cpp rule-of-three memory double-free cwe-1098
Source internal/sast/rules/vnx-1098.rego

Overview

VNX-1098 maps to CWE-1098: Data Element containing Pointer Item without Proper Copy Control Element. It reports the destructor of a C++ class that owns memory through a raw pointer, releasing it with delete, delete[] or free(), when no copy constructor for that class is declared anywhere in the scanned files.

Why This Matters

Without a user-declared copy constructor the compiler generates one that copies the pointer, not what it points to. Pass the object by value, return it, or put it in a std::vector, and two objects own the same memory: the first destructor frees it and the second frees it again, or reads it after it was freed.

Not reported: classes with a copy constructor, including a deleted one (Name(const Name&) = delete), classes that declare a move constructor or move assignment (which suppresses the implicit copy), classes marked non-copyable (boost::noncopyable, DISALLOW_COPY_AND_ASSIGN, Q_DISABLE_COPY), destructors that release nothing, and comments.

What Gets Flagged

class Buffer {
public:
    explicit Buffer(std::size_t n) : data_(new char[n]), size_(n) {}
    ~Buffer() { delete[] data_; }      // FLAGGED: no Buffer(const Buffer&)
private:
    char* data_;
    std::size_t size_;
};

Session::~Session()                     // FLAGGED
{
    delete user_;
}

Remediation

  1. Hold the memory in std::unique_ptr, std::vector or std::string and drop the destructor (rule of zero).
  2. Otherwise define the copy constructor and copy assignment to deep-copy, or delete them (= delete).
  3. For a confirmed false positive, add a // vulnetix-ignore: VNX-1098 comment on the line.

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

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

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