CWE-214, Invocation of Process Using Visible Sensitive Information, applies when a process is started with sensitive command-line arguments, environment variables or other elements that other processes on the operating system can see.
Many operating systems let a user list information about processes owned by other users, including command-line arguments and environment variable settings. If those contain credentials, anyone on the host can read them.
Scripts, deployment tooling, CI jobs and wrapper programs are the usual culprits.
How it happens
A developer needs to hand a secret to another program and takes the shortest route: a flag.
# Vulnerable: the password is visible in process listings
mysql -u admin -pS3cretPass -h db.internal mydb
# Vulnerable: secret in argv of a child process
subprocess.run(["backup-tool", "--password", db_password])
While that command runs, a process listing such as ps shows the full line to other local users. The record's examples are direct about it:
- CVE-2023-38994: an IAM product includes an LDAP password in a process call, allowing local users to obtain the password.
- CVE-2001-1565: a username and password on the command line let local users view them via ps or similar tools.
- CVE-2005-1387 and CVE-2005-2291: a password passed on the command line.
What an attacker gains
MITRE lists confidentiality: reading application data. The attacker is a local user, or code running as one, who can then use the credential against the product or related resources.
Shared build servers, multi-user hosts and containers that share a process namespace make this more likely than it sounds.
How to find it
MITRE lists no detection methods. These checks work well:
- Grep your scripts, pipelines and code for
--password,-p,--token,--secretand similar flags. - Search for subprocess and exec calls that build argument lists from variables holding secrets.
- While a job runs, list processes as a different user and read what shows.
- Run a secrets scan across the repository, since command lines with credentials often end up committed.
Click through it at your own pace, or open it full screen.
How to fix it
MITRE gives no mitigations for this entry, so these are practical steps drawn from the weakness itself: keep secrets out of anything other processes can list.
- Read from a file with tight permissions. Pass the path, not the value, and set the file to be readable only by the owning user.
- Use standard input. Many tools accept a password on stdin or a prompt.
- Use a secrets manager or credential helper that the program calls itself.
- Be careful with environment variables. MITRE names them as visible to other processes in some systems. Check how your platform exposes them before relying on them.
# Safer: pass a file path, keep the value out of argv
subprocess.run(["backup-tool", "--password-file", "/run/secrets/db_pass"])
# Safer: read from stdin
printf '%s' "$DB_PASS" | backup-tool --password-stdin
Finally, rotate any credential that has already appeared on a command line, since you cannot know who read it.
Quick check
Is an environment variable safer than a flag?
Not necessarily. MITRE lists environment variable settings alongside arguments as things other processes can see on some operating systems.
What do we do about a credential already used this way?
Treat it as exposed to local users and rotate it, then change how it is passed.