Skip to content

VNX-777: Regular Expression without Anchors

Allow-list validation regexes anchored at only one end, or bounded by a length and anchored at neither, tested with a search-semantics API; Ruby ^/$ line anchors in validation.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-777
Severity Medium
SARIF level warning
Kind sast
Languages Go, Java, JavaScript / TypeScript, PHP, Python, Ruby
CWE CWE-777
CAPEC CAPEC-97
ATT&CK T1557
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 regex input-validation cwe-777
Source internal/sast/rules/vnx-777.rego

Overview

This rule flags an allow-list regular expression (a single character class, \d, \w or . with +, * or {n,m}) used to validate a value when it is anchored at only one end, or is bounded by a length quantifier and anchored at neither, so the check passes as soon as part of the value conforms. It covers Python re.search/re.match, JavaScript RegExp.test and String.match/search, Go regexp.MatchString, Java Matcher.find()/lookingAt(), PHP preg_match and Ruby =~/match?, and in Ruby ^/$ (line anchors) used instead of \A/\z. Patterns are read at the call or from a named constant compiled in the same file. This maps to CWE-777: Regular Expression without Anchors.

Not reported: fully anchored patterns, re.fullmatch, String.matches, negated classes, unanchored patterns without a length bound (a “contains a digit” test is legitimate), match objects used to extract text, comments and strings.

Why This Matters

^[a-z0-9]+ accepts abc; rm -rf /, and a Ruby /^[a-z0-9]+$/ accepts abc\n<script> because $ matches at the newline. The validation passes and the rest of the value reaches the sink unchecked.

What Gets Flagged

if not re.match(r"[a-zA-Z0-9_]+", name):     # FLAGGED: no end anchor
    abort(400)
if (!/[0-9]{1,10}$/.test(req.params.id)) {   // FLAGGED: no start anchor
validates_format_of :handle, with: /^[a-z_]+$/i, multiline: true   # FLAGGED: line anchors

Remediation

if not re.fullmatch(r"[a-zA-Z0-9_]+", name):
    abort(400)
if (!/^[0-9]{1,10}$/.test(req.params.id)) { ... }
validates_format_of :handle, with: /\A[a-z_]+\z/i

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

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

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