Skip to content

VNX-340: Generation of Predictable Numbers or Identifiers

Detects secrets produced by predictable identifier generators: time-based UUIDs (v1/v6), name-based UUIDs (v3/v5) and PHP uniqid(), when stored under, keyed by or returned as a secret. Python, JavaScript/TypeScript, PHP, Go, Java, Kotlin and Ruby.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-340
Severity Medium
SARIF level warning
Kind sast
Languages Python, JavaScript / TypeScript, PHP, Go, Java, Kotlin, Ruby
CWE CWE-340
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags randomness predictable uuid cwe-340
Source internal/sast/rules/vnx-340.rego

Overview

VNX-340 maps to CWE-340: Generation of Predictable Numbers or Identifiers. Some identifier generators are unique but not unpredictable. A version 1 or 6 UUID is a timestamp plus the host’s MAC address or a fixed node id; a version 3 or 5 UUID is a hash of its input, so anyone who knows the input (an email address, a user name) computes the same value; PHP uniqid() is the current time in hex. None of them is a secret.

The rule reports uuid.uuid1()/uuid3()/uuid5(), JavaScript uuid v1/v3/v5/v6, Ramsey Uuid::uuid1()/uuid3()/uuid5()/uuid6(), Go uuid.NewUUID()/NewMD5/NewSHA1 and gofrs NewV1/NewV3/NewV5/NewV6, Java UUID.nameUUIDFromBytes() and the time- and name-based generators of java-uuid-generator and UuidCreator, Ruby Digest::UUID.uuid_v3/uuid_v5 and UUIDTools timestamp_create/md5_create/sha1_create, and PHP uniqid(), when the result is stored under, keyed by or returned as a secret (token, password, secret, nonce, salt, OTP, CSRF, session id, API key, reset/confirmation/invite code, session cookie), directly or through a variable that reaches such a name within six lines.

What Gets Flagged

# FLAGGED: time-based and name-based UUIDs as secrets
session_id = str(uuid.uuid1())

def new_reset_token(user):
    return uuid.uuid5(uuid.NAMESPACE_DNS, user.email).hex
// FLAGGED: uniqid() is the clock
$_SESSION['session_token'] = md5(uniqid());
// FLAGGED: a hash of the email address
String resetToken = UUID.nameUUIDFromBytes(email.getBytes(StandardCharsets.UTF_8)).toString();

What Is Not Flagged

  • Random UUIDs: uuid4(), crypto.randomUUID(), UUID.randomUUID(), uuid.New(), SecureRandom.uuid, Uuid::uuid4().
  • uniqid() and time-based UUIDs used as file names, request ids, cache keys and other identifiers that are not secrets.
  • Values combined on the same line with a CSPRNG (random_bytes, secrets, crypto.randomBytes), test files, and the call in comments or string literals.

Remediation

  1. Use a random (version 4) UUID or, better, a CSPRNG token of at least 128 bits: secrets.token_urlsafe(32), crypto.randomBytes(32), bin2hex(random_bytes(32)), SecureRandom.urlsafe_base64(32).
  2. For confirmed false positives, add a # vulnetix-ignore: VNX-340 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-340
// nosec vnx-340

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

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