Skip to content

VNX-350: Reliance on Reverse DNS Resolution for a Security-Critical Action

An access decision made on the host name a reverse DNS lookup returned for the peer's address, without forward confirmation, in Python, Java, Go, JavaScript/TypeScript, PHP and Ruby.

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

Overview

VNX-350 maps to CWE-350: Reliance on Reverse DNS Resolution for a Security-Critical Action. It reports a reverse DNS lookup whose result is compared, on the same line or within the next eight lines, to decide something:

  • Python socket.gethostbyaddr()/getnameinfo(), socket.getfqdn(address) (not the argument-less local form), dnspython resolve_address();
  • Java request.getRemoteHost(), InetAddress.getCanonicalHostName()/getHostName();
  • Go net.LookupAddr(); Node dns.reverse()/dns.promises.reverse();
  • PHP gethostbyaddr() and $_SERVER['REMOTE_HOST']; Ruby Resolv.getname().

The comparison may be on the name directly, a loop variable over the names or a callback parameter: endsWith, HasSuffix, equals, ==, in, includes, preg_match, =~.

Why This Matters

The PTR record for an address is published by whoever controls that address block. An attacker sets the PTR for their own IP to gw.example.com and passes any suffix or allowlist check on the name.

Not reported: forward-confirmed lookups (the name resolved again with gethostbyname, getaddrinfo, LookupHost, getAllByName or dns.lookup within the window, as done to verify Googlebot), names that are only logged or displayed, null and empty checks, the local host name (getLocalHost()), comments and string literals.

What Gets Flagged

host = socket.gethostbyaddr(request.remote_addr)[0]
if host.endswith(".corp.example.com"):
    return True
if (request.getRemoteHost().endsWith(".internal.example.com")) {
names, err := net.LookupAddr(ip)
// ...
for _, n := range names {
	if strings.HasSuffix(n, ".example.com.") {

Remediation

  1. Decide on the peer’s address (an IP allowlist or network range), or on authentication, not on its name.
  2. If a name is required, forward-confirm it: resolve the name returned by the reverse lookup and accept it only when the peer’s address is among the results.

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

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

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