CWE-555, J2EE Misconfiguration: Plaintext Password in Configuration File, is what it says. The J2EE application stores a plaintext password in a configuration file. MITRE adds that this allows anyone who can read the file to access the password-protected resource, making it an easy target for attackers.
How it happens
Java enterprise applications read their settings from files: data source definitions, connection settings, service credentials. The quick way to make a data source work is to type the password into the file.
<!-- Vulnerable: password sits in the file as text -->
<Resource name="jdbc/appdb" type="javax.sql.DataSource"
username="appuser" password="plain-text-password"
url="jdbc:postgresql://db.internal/appdb"/>
The file then travels. It is checked into version control, copied to servers, included in backups and attached to support tickets. Each copy is another place to read the password.
What an attacker gains
MITRE lists bypassing a protection mechanism as the access control impact. Whoever reads the file holds working credentials for the database or service and does not need to defeat any login.
How to find it
- Search configuration files and deployment descriptors for
password,passwdand credential attributes. - Search the repository history too.
- Run a secrets scan across configuration and build artifacts.
- Check file permissions on configuration directories.
How to fix it
MITRE's mitigations, both at design level:
- Do not hardwire passwords into your software.
- Use industry standard libraries to encrypt passwords before storage in configuration files.
Modern practice goes a step further. Keep the password out of the file by reading it from a secrets manager or an environment variable supplied at deploy time, and restrict who can read the configuration. If a plaintext password was ever committed or copied around, rotate it.
<!-- Better: value resolved at deploy time, not stored in the file -->
<Resource name="jdbc/appdb" type="javax.sql.DataSource"
username="appuser" password="${DB_PASSWORD}"
url="jdbc:postgresql://db.internal/appdb"/>
Whether a placeholder like this is resolved depends on your application server, so confirm how yours handles it.
Try it yourself
This demo shows a secrets scan finding credentials in files.
Click through it at your own pace, or open it full screen.
Quick check
Does encrypting the password in the file solve everything?
It helps, and MITRE recommends it. The encryption key then needs its own protection, which is why keeping secrets out of files is stronger.
The file is only readable by the app user. Is that enough?
It limits one copy. Copies in repositories, backups and tickets are not covered, so avoid storing the secret in the file.