VNX-259: Hard-coded password passed to an authentication or connection API
Reports a string literal passed positionally as the password of an authentication or connection call (smtplib login, HTTPBasicAuth, JNDI SECURITY_CREDENTIALS, DriverManager.getConnection, new Sequelize, LDAP bind, mysqli_connect, new PDO, Net::SMTP.start, smtp.PlainAuth, SetBasicAuth, NetworkCredential and similar).
| Field | Value |
|---|---|
| Rule ID | VNX-259 |
| Severity | Critical |
| SARIF level | error |
| Kind | sast |
| Languages | C#, Go, Java, JavaScript / TypeScript, PHP, Python, Ruby |
| CWE | CWE-259 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:C/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:C/DI:H/EX:H/EC:N/P:W |
| Tags | hardcoded-credentials cwe-259 |
| Source | internal/sast/rules/vnx-259.rego |
Overview
A password written into the call that uses it ships in the source and in every build, is visible to everyone with repository access, and cannot be rotated without a release. This maps to CWE-259: Use of Hard-coded Password.
This rule covers positional arguments. A literal assigned to a password-named variable, key, keyword argument or configuration entry is reported by VNX-SEC-014 (and in Java by VNX-JAVA-025).
What Gets Flagged
- Python:
.login(user, "pw")(smtplib, ftplib, imaplib; the user may be a variable),HTTPBasicAuth/HTTPDigestAuth(user, "pw"),auth=("u", "pw"),pymysql/MySQLdb.connect(host, user, "pw"), LDAPsimple_bind_s(dn, "pw"). - Java:
env.put(Context.SECURITY_CREDENTIALS, "pw"),Transport.send(msg, user, "pw"),transport.connect(host, user, "pw"),new UsernamePasswordAuthenticationToken("u", "pw"),DriverManager.getConnection(url, user, "pw"),new PasswordAuthentication(user, "pw".toCharArray()). - JavaScript:
new Sequelize(db, user, "pw"),pass: "pw"inside anauth: { }object (nodemailer), express-basic-authusers: { name: "pw" },.auth("u", "pw"), ldapjsclient.bind("cn=admin,dc=example,dc=org", "pw", cb). - PHP:
mysqli_connect/new mysqli/mysql_connect(host, user, "pw"),new PDO(dsn, user, "pw"),ldap_bind,ftp_login. - Ruby:
ftp.login(user, "pw"),.basic_auth(user, "pw"),Net::SMTP.start(host, port, helo, user, "pw", :login). - Go:
smtp.PlainAuth(id, user, "pw", host),SetBasicAuth(user, "pw"),url.UserPassword(user, "pw"),ssh.Password("pw"), go-ldapl.Bind("cn=svc,dc=example,dc=com", "pw"). - C#:
new NetworkCredential(user, "pw").
server.login("alerts@example.org", "Wint3r-Is-Coming") # flagged
auth := smtp.PlainAuth("", "alerts@example.org", "Sm7p-Passw0rd", host) // flagged
Not flagged: values from the environment, configuration or a variable, empty strings, templated values (${...}, {{...}}, %s, $var), placeholders (xxx, ***, <password>, your-password, or the bare words password, pass, secret, user), comments, strings that only mention the call, and test code.
Remediation
server.login(os.environ["SMTP_USER"], os.environ["SMTP_PASSWORD"])
Load credentials from a secret manager or the environment at runtime, and rotate any password that has been committed.
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-259
// nosec vnx-259
Or record an ignore rule: vulnetix ignore add --rule vnx-259 --reason "...". See Suppressing findings.