VNX-522: Insufficiently Protected Credentials: credential file readable by other users
Detects a password, API key, token, private key or credentials file written to a file that other local users can read: Go WriteFile/OpenFile with a group- or world-readable mode or os.Create of a credential path, Python os.open/os.chmod with such a mode, pathlib write_text/write_bytes or open() of a credential file with no owner-only mode, Node fs.writeFile without mode 0o600, and Java Files.write/FileWriter without owner-only POSIX permissions.
| Field | Value |
|---|---|
| Rule ID | VNX-522 |
| Severity | High |
| SARIF level | error |
| Kind | sast |
| Languages | Go, Java, JavaScript / TypeScript, Python |
| CWE | CWE-522 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:H/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H |
| Tags | credentials-protection file-permissions cwe-522 |
| Source | internal/sast/rules/vnx-522.rego |
Overview
VNX-522 maps to CWE-522: Insufficiently Protected Credentials. A credential saved to disk with the default or a permissive mode (0644, 0664, 0755) can be read by every local user and by any process running as another account. The rule reports a write whose path or written value names a credential (password, API key, access/refresh/session token, private key, a credentials, token, secret, .netrc or .pgpass file) when the file ends up readable by group or others:
- Go
os.WriteFile,ioutil.WriteFileandos.OpenFilewith a group/other-readable mode (oros.ModePerm); - Python
os.open(..., 0o644)andos.chmod(..., 0o644), andopen(path, "w")of a credential path, or of a path then written a credential, in a file that never restricts the mode; - JavaScript/TypeScript
fs.writeFile,writeFileSyncandfs.promises.writeFilewith nomodeor a readable one; - Java
Files.write/writeString,FileWriter,FileOutputStreamandPrintWriteron a credential path (forFiles.write/writeString, also a credential as the value written) with no owner-only POSIX permissions in the file.
What Gets Flagged
return os.WriteFile(filepath.Join(dir, "token"), []byte(token), 0644) // FLAGGED
f, err := os.Create(filepath.Join(dir, "token")) // FLAGGED: 0666 before umask
with open(token_file, "w") as f: # FLAGGED (no chmod to 0o600 anywhere in the file)
json.dump({"token": token}, f)
Path("~/.netrc").expanduser().write_text(netrc_text) # FLAGGED
fs.writeFileSync(credPath, JSON.stringify({ accessToken })); // FLAGGED: no mode
What Is Not Flagged
Owner-only modes (0600, 0o400, { mode: 0o600 }, PosixFilePermissions.fromString("rw-------")), a Python file that creates or chmods the file to 0o600, files that are not credentials (reports, logs, tokenizer vocabularies), reads, comments and test code. Credentials kept in cookies, browser storage or recoverable encodings are VNX-256, VNX-257 and VNX-261.
Remediation
- Create credential files owner-only:
os.WriteFile(p, b, 0o600),os.open(p, flags, 0o600),fs.writeFileSync(p, data, { mode: 0o600 }),Files.createFile(p, PosixFilePermissions.asFileAttribute(...("rw-------"))). - Keep the containing directory private (0700) as well.
- Prefer the operating system’s credential store or a secret manager to plain files.
References
- CWE-522: Insufficiently Protected Credentials
- CWE-732: Incorrect Permission Assignment for Critical Resource
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-522
// nosec vnx-522
Or record an ignore rule: vulnetix ignore add --rule vnx-522 --reason "...". See Suppressing findings.