VNX-224: Obscured Security-relevant Information by Alternate Name
A log call writes a credential (password, secret, token, API key) base64-encoded, inline or through a variable, in JavaScript, TypeScript or Python. Base64 is a reversible alternate name for the value, not a protection.
| Field | Value |
|---|---|
| Rule ID | VNX-224 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python |
| CWE | CWE-224 |
| 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 | obscured-security-info cwe-224 logging base64 |
| Source | internal/sast/rules/vnx-224.rego |
Overview
VNX-224 maps to CWE-224: Obscured Security-relevant Information by Alternate Name. It reports a log call (console.*, logger.*, log.*, logging.*, winston, pino) whose argument is btoa(), Buffer.from(x).toString('base64') or base64.b64encode() (and the urlsafe, standard, b32, b16 and encodebytes forms) of a value named as a secret, either inline or through a variable assigned from such an encoding in the six lines above.
Why This Matters
Encoding a credential before logging it looks like masking, but anyone who reads the log decodes it in one step. The log then holds the secret itself under a different spelling, which also defeats log scanners that look for the plain value.
A log call broken over several lines is judged as the whole call. The secret word has to end the name, so passwordPolicy, tokenizer_output and apiKeyId are not credentials.
Not reported: base64 of values not named as secrets, the .length/len() of an encoded value, an encoded credential that is built but not logged (a Basic auth header), hashed values (hashlib, sha256, createHash, digest, bcrypt), the pattern inside a plain string literal or a comment, and test code. The wider CWE-224 sense (recording an entity under a non-canonical name) is not decidable line by line and is not judged.
What Gets Flagged
console.log("login attempt", username, btoa(password));
logger.info(`issued ${Buffer.from(accessToken).toString("base64")} to ${user.id}`);
logger.info("auth %s %s", username, base64.b64encode(password.encode()))
masked = base64.b64encode(api_key.encode()).decode()
log.warning("connecting with key %s", masked)
Remediation
- Do not log credentials in any encoding.
- When a log line must identify a key, log a non-reversible identifier: a key id, or a short prefix of a hash of the value.
References
- CWE-224: Obscured Security-relevant Information by Alternate Name
- CWE-532: Insertion of Sensitive Information into Log File
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-224
// nosec vnx-224
Or record an ignore rule: vulnetix ignore add --rule vnx-224 --reason "...". See Suppressing findings.