Skip to content

VNX-598: Credential or secret sent in a GET query string

Reports URLs that carry an interpolated password, API key, client secret or token as a query parameter (including ?key= given a variable named for an API key), request helpers given such a key in their params object, and HTML forms that submit a password field by GET.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-598
Severity Medium
SARIF level warning
Kind sast
Languages Go, Java, JavaScript / TypeScript, PHP, Python, HTML
CWE CWE-598
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 sensitive-data-in-url credentials logging cwe-598
Source internal/sast/rules/vnx-598.rego

Overview

VNX-598 maps to CWE-598: Use of GET Request Method With Sensitive Query Strings. A query string is written to web server and proxy access logs, kept in browser history and sent onward in the Referer header.

The rule reports:

  • a URL built in code whose query (the line opens one with ?name=) carries a parameter named password, passwd, pwd, pass, passphrase, secret, client_secret, api_key, apikey, api-key, access_token, auth_token, token, session_id, sessionid or ssn, whose value is interpolated (concatenation, f-string or template-literal placeholder, %s/%v, PHP $variable);
  • a GET helper (requests.get, axios.get, http.get) given such a key in its params object;
  • an HTML or template <form> that submits a password input by GET: method="get", or no method at all (GET is the default) in .html, .htm, .php, .jsp, .ejs, .hbs, .twig, .jinja and .erb files.

It does not report form-encoded POST bodies (grant_type=password&password=...), credentials in headers or POST data, constant example URLs (?api_key=YOUR_API_KEY), lookalike parameters (pageToken, next_token, show_password_field), otpauth:// provisioning URIs, forms submitted by POST or by a script handler (onsubmit, ngSubmit, Angular bindings, @submit), or comments.

What Gets Flagged

url = f"{base}/login?user={username}&password={password}"            # FLAGGED
requests.get("https://api.example.com/v1/items?api_key=" + api_key)   # FLAGGED
requests.get(url, params={"q": q, "access_token": token})             # FLAGGED

# NOT FLAGGED
requests.get(url, headers={"X-Api-Key": api_key})
requests.post(base + "/token", data="grant_type=password&password=" + password)
<form action="/session" method="get">      <!-- FLAGGED: has a password input -->
  <input type="password" name="pw">
</form>

Remediation

  1. Send credentials in a POST body or an Authorization header, never in the URL.
  2. Give every login form method="post".
  3. Where an API only accepts a key in the query string, keep the URL out of logs and rotate the key.

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

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

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