VNX-SEC-074: Kubernetes Secret manifest with credential data
Reports each credential entry with a literal value in the data: or stringData: block of a committed Kubernetes Secret manifest, excluding templated, referenced, SOPS-encrypted, empty and placeholder values and other kinds such as SealedSecret.
| Field | Value |
|---|---|
| Rule ID | VNX-SEC-074 |
| Severity | High |
| SARIF level | error |
| Kind | secrets |
| Languages | Any file |
| CWE | CWE-798 |
| CAPEC | CAPEC-191 |
| ATT&CK | T1552.001 |
| 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 | secrets kubernetes credentials |
| Source | internal/sast/rules/vnx-sec-074.rego |
Overview
This rule reads every YAML document whose top-level kind is Secret (multi-document files included) and reports each entry in its data: or stringData: block whose key names a credential (password, token, secret, key, auth, credentials, connection string, .dockerconfigjson) and whose value is a literal. Base64 in data: is an encoding, not encryption.
Why This Matters
Hardcoded kubernetes secret manifest with credentials values are routinely scraped by automated bots within minutes of a public push, and then used to access the account, exfiltrate data, or pivot into downstream services. Once the credential is in git history it is permanently in third-party hands.
What Gets Flagged
# FLAGGED: the password and API key entries
apiVersion: v1
kind: Secret
metadata:
name: billing-api
type: Opaque
data:
username: YmlsbGluZw== # not a credential key, not flagged
password: Ums5eVcyczlMcTd6
stripe-api-key: c2stbGl2ZS1iaWxsaW5nLTQ4Mjk3MzE1OTA=
Not flagged:
- Helm and other templated values (
{{ .Values.db.password | b64enc }}),${VAR}and$(VAR)references,<placeholder>values and empty strings. - Default or placeholder words (
password,changeme,admin,xxxx...), including their base64 encodings. - SOPS-encrypted values (
ENC[AES256_GCM,data:...]), release-pipeline token substitutions (#{DbPassword}#,__API_TOKEN__,%%TOKEN%%) and argocd-vault-plugin<path:...>references. SealedSecret,ExternalSecret,ConfigMapand other kinds, andsecretKeyRefreferences.- Test, fixture and testdata files.
Remediation
- Revoke the leaked credential in the provider’s console immediately.
- Replace with a short-lived alternative, OAuth 2.0 access tokens, IAM role assumption, OIDC federation, wherever the platform supports it.
- Store the new credential in a secrets manager (AWS Secrets Manager, HashiCorp Vault, GitHub Actions secrets, Doppler).
- Audit the provider’s access logs for activity you did not initiate between the leak and the revocation.
- Purge from git history with
git filter-repoor BFG, then re-scan with gitleaks/truffleHog to confirm no other secrets remain. - Enable push protection so future commits are blocked at the developer machine.
References
- CWE-798: Use of Hard-coded Credentials
- gitleaks
- truffleHog
- OWASP Credentials Management Cheat Sheet
- MITRE ATT&CK T1552.001 – Credentials In Files
- git-filter-repo
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-sec-074
// nosec vnx-sec-074
Or record an ignore rule: vulnetix ignore add --rule vnx-sec-074 --reason "...". See Suppressing findings.