VNX-262: Not Using Password Aging
Password aging is switched off where it is configured: an AWS IAM password policy with no maximum age, Entra ID DisablePasswordExpiration, the Active Directory DONT_EXPIRE_PASSWORD flag, PowerShell -PasswordNeverExpires, or Linux PASS_MAX_DAYS/chage set to 99999 or -1.
| Field | Value |
|---|---|
| Rule ID | VNX-262 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Java, JavaScript / TypeScript, Python, Terraform, Shell, Dockerfile, PowerShell |
| CWE | CWE-262 |
| 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 | password-aging cwe-262 |
| Source | internal/sast/rules/vnx-262.rego |
Overview
VNX-262 maps to CWE-262: Not Using Password Aging. It reports configuration and provisioning code that leaves passwords valid forever: an account password policy that sets no maximum age, or a user or account created with expiry disabled.
Why This Matters
A password that never expires stays usable for as long as it is known. A credential leaked in a breach, phished or left in a script years ago still opens the account, and a service account with a non-expiring password is a favourite foothold because nobody notices it being used. Modern guidance (NIST SP 800-63B) prefers rotation on evidence of compromise over a fixed schedule, but that requires breached-password screening and MFA; switching expiry off without them leaves no limit at all.
What Gets Flagged
resource "aws_iam_account_password_policy" "strict" { # no max_password_age
minimum_password_length = 14
}
resource "azuread_user" "svc" {
disable_password_expiration = true
}
iam.update_account_password_policy(MinimumPasswordLength=14, RequireSymbols=True)
user = {"passwordPolicies": "DisablePasswordExpiration"}
conn.modify(dn, {"userAccountControl": [("MODIFY_REPLACE", [66048])]})
UpdateAccountPasswordPolicyRequest.builder().minimumPasswordLength(14).build();
new BasicAttribute("userAccountControl", "66048");
PASS_MAX_DAYS 99999
chage -M -1 deploy
New-LocalUser -Name "svc" -Password $pw -PasswordNeverExpires
Set-ADUser -Identity svc-backup -PasswordNeverExpires $true
net accounts /maxpwage:unlimited
Not flagged: a policy that sets a maximum age (an over-long one is VNX-263), reading or comparing these settings (== "DisablePasswordExpiration", uac & UF_DONT_EXPIRE_PASSWD, a -Filter string), account expiry (chage -E -1), values of false/$false, and the names in comments or string literals.
Remediation
- Set a maximum password age in the account policy (
max_password_age,MaxPasswordAge,PASS_MAX_DAYS), or - if you follow NIST SP 800-63B and do not expire passwords on a schedule, enforce MFA and breached-password screening and record that decision where the policy is defined.
- Give service accounts managed or rotated credentials (gMSA, IAM roles, workload identity) instead of a password that never expires.
References
- CWE-262: Not Using Password Aging
- NIST SP 800-63B, Memorized Secret Verifiers
- CIS AWS Foundations Benchmark: IAM password policy
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-262
// nosec vnx-262
Or record an ignore rule: vulnetix ignore add --rule vnx-262 --reason "...". See Suppressing findings.