VNX-487: Reliance on Package-level Scope
A credential is held in a Java field with no access modifier, so the only thing protecting it is package scope: a field of a top-level class, declared at member level without private/protected/public, that is either a key type (SecretKey, PrivateKey, Key, KeyPair, Credentials, any name) or a String/char[]/byte[] whose name says it is a password, passphrase, secret, API key, token, credential or private key. Java packages are open (any class that declares the same package, or a jar on the class path that splits it, can read the field), so this is not access control. Not reported: private, protected and public fields (public exposure is VNX-493), fields of an interface (implicitly public), injected fields carrying an annotation, constants that name a parameter, header, field, attribute or length rather than holding a value (PASSWORD_PARAM, TOKEN_HEADER), local variables, nested classes, test code and comments.
| Field | Value |
|---|---|
| Rule ID | VNX-487 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Java |
| CWE | CWE-487 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | package-level-scope access-modifier credentials cwe-487 |
| Source | internal/sast/rules/vnx-487.rego |
Overview
VNX-487 maps to CWE-487: Reliance on Package-level Scope. It reports credentials kept in package-private (default access) fields, where package scope is the only barrier between the secret and other code.
Why This Matters
A Java package is not a security boundary. Any class that declares package com.acme.auth;, including one in another jar on the class path, can read a package-private field. A password or key left at default access is readable by far more code than its author intended.
What Gets Flagged
public class TokenStore {
String apiToken; // FLAGGED
char[] masterPassword; // FLAGGED
static String adminPassword = System.getenv("ADMIN_PW"); // FLAGGED
SecretKey sessionKey; // FLAGGED (key type, any name)
private String hidden; // not flagged
static final String PASSWORD_PARAM = "password"; // not flagged: names a parameter
}
Remediation
- Declare the field
privateand expose only the operation callers need (sign, verify), not the secret. - Clear
char[]/byte[]secrets after use. - If the package must stay closed, seal it in the jar manifest (
Sealed: true) or use JPMS modules that do not export it.
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-487
// nosec vnx-487
Or record an ignore rule: vulnetix ignore add --rule vnx-487 --reason "...". See Suppressing findings.