Skip to content

VNX-359: Private personal information written to logs or standard output

Reports logging and print calls in Python, JavaScript/TypeScript and Java whose arguments name a social security number, passport number, date of birth, national ID, tax ID, driver's licence or medical record number.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-359
Severity Medium
SARIF level warning
Kind sast
Languages Java, JavaScript / TypeScript, Python
CWE CWE-359
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 pii-exposure logging privacy cwe-359
Source internal/sast/rules/vnx-359.rego

Overview

VNX-359 maps to CWE-359: Exposure of Private Personal Information to an Unauthorized Actor. It reports a value that identifies a person passed to a logging call or printed:

  • Python: logging/logger/log/app.logger calls and print.
  • JavaScript/TypeScript: console.*, and logger/log/winston/pino/bunyan/req.log calls.
  • Java: log/logger/LOG/LOGGER calls and System.out/System.err print methods.

A call is reported when its arguments, followed across up to four continuation lines and including f-string and template-literal interpolations, name a social security number, passport number, date of birth, national ID or national insurance number, tax ID, driver’s licence number or medical record number as an identifier, property, getter or object key (applicant.ssn, customer.getSsn(), dateOfBirth, passport_number, { ssn }).

Not reported: the words inside a string literal ("Collecting SSN"), lookalike names (has_passport, dobVerified, ssnMasked), arguments that are masked, redacted, hashed, truncated to the last four or reduced to a null/presence check (each argument is judged on its own, so a hashed argument does not excuse a raw one beside it), comments, and test files. Credentials and card numbers in logs are VNX-NODE-031 and VNX-GO-040.

Why This Matters

Logs are copied to log shippers, search clusters, support tools and backups, and they are read by many people who have no business seeing a customer’s identity documents. A logged SSN or passport number is a reportable personal-data exposure under most privacy laws, and it outlives the record it came from.

What Gets Flagged

# FLAGGED
logger.info("registering applicant %s ssn=%s", applicant.name, applicant.ssn)
logging.debug(f"passport {applicant.passport_number} dob {applicant.date_of_birth}")
// FLAGGED
log.info("Onboarding {} with SSN {}", customer.getName(), customer.getSsn());
System.out.println("DOB: " + customer.getDateOfBirth());
# NOT FLAGGED
logger.info("ssn on file: %s", mask(applicant.ssn))
logger.info("Collecting SSN and date of birth for applicant %s", applicant.id)

Remediation

  1. Log a record identifier, not the personal data itself.
  2. Where a value must appear, mask it (last four digits at most) through one shared helper.
  3. Add a log filter or structured-logging redaction for known PII field names as a backstop.

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

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

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