Skip to content

Commit 7ba2371

Browse files
committed
Password in Java EE configuration files
1 parent 09cfb24 commit 7ba2371

File tree

7 files changed

+167
-0
lines changed

7 files changed

+167
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
<overview>
4+
<p>
5+
Storing a plaintext password in a configuration file allows anyone who can read the file to access the password-protected resources. Therefore it is a common attack vector.
6+
</p>
7+
</overview>
8+
9+
<recommendation>
10+
<p>
11+
Passwords stored in configuration files should be encrypted. Utilities provided by application servers like keystore and password vault can be used to encrypt and manage passwords.
12+
</p>
13+
</recommendation>
14+
15+
<example>
16+
<p>
17+
In the first example, the password of a datasource configuration is stored in cleartext in the context.xml file of a Java EE application.
18+
</p>
19+
20+
<p>
21+
In the second example, the password of a datasource configuration is encrypted and managed by a password vault.
22+
</p>
23+
<sample src="context.xml" />
24+
</example>
25+
26+
<references>
27+
<li>
28+
CWE:
29+
<a href="https://cwe.mitre.org/data/definitions/555.html">CWE-555: J2EE Misconfiguration: Plaintext Password in Configuration File</a>
30+
</li>
31+
<li>
32+
RedHat Security Guide:
33+
<a href="https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/6.1/html/security_guide/Store_and_Retrieve_Encrypted_Sensitive_Strings_in_the_Java_Keystore">STORE AND RETRIEVE ENCRYPTED SENSITIVE STRINGS IN THE JAVA KEYSTORE</a>
34+
</li>
35+
<li>
36+
SonarSource:
37+
<a href="https://rules.sonarsource.com/java/RSPEC-2068">Hard-coded credentials are security-sensitive</a>
38+
</li>
39+
</references>
40+
</qhelp>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @name Password in configuration file
3+
* @description Finds passwords in configuration files.
4+
* @kind problem
5+
* @id java/password-in-configuration
6+
* @tags security
7+
* external/cwe/cwe-555
8+
* external/cwe/cwe-256
9+
* external/cwe/cwe-260
10+
*/
11+
12+
import java
13+
14+
predicate isNotPassword(XMLAttribute a) {
15+
a.getValue() = "" // Empty string
16+
or
17+
a.getValue().regexpMatch("\\$\\{.*\\}") // Variable placeholder ${password}
18+
or
19+
a.getValue().charAt(a.getValue().length() - 1) = "=" // A basic check of encrypted passwords ending with padding characters, which could be improved to be more accurate.
20+
}
21+
22+
from XMLAttribute a
23+
where
24+
a.getName().toLowerCase() in ["password", "pwd"] and not isNotPassword(a) // Attribute name "password" or "pwd"
25+
or
26+
exists(
27+
XMLAttribute b // name/value pair like <property name="password" value="mysecret"/>
28+
|
29+
b.getElement() = a.getElement() and
30+
a.getName().toLowerCase() = "name" and
31+
a.getValue().toLowerCase() in ["password", "pwd"] and
32+
b.getName().toLowerCase() = "value" and
33+
not isNotPassword(b)
34+
)
35+
or
36+
a.getValue().regexpMatch("(?is).*(pwd|password)\\s*=(?!\\s*;).*") // Attribute value matches password pattern
37+
select a, "Avoid plaintext passwords in configuration files."
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Context>
3+
<!-- BAD: Password of datasource is in not encrypted -->
4+
<Resource name="jdbc/exampleDS" auth="Container" type="javax.sql.DataSource"
5+
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
6+
username="root" password="1234"
7+
driverClassName="com.mysql.jdbc.Driver"
8+
url="jdbc:mysql://www.example.com:3306/proj"/>
9+
10+
<!-- GOOD: Password is encrypted and stored in a password vault -->
11+
<Resource name="jdbc/exampleDS" auth="Container" type="javax.sql.DataSource"
12+
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
13+
username="root" password="${VAULT::exampleDS::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0}"
14+
driverClassName="com.mysql.jdbc.Driver"
15+
url="jdbc:mysql://www.example.com:3306/proj"/>
16+
17+
</Context>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| applicationContext.xml:11:6:11:50 | name=password | Avoid plaintext passwords in configuration files. |
2+
| context.xml:4:5:8:63 | password=1234 | Avoid plaintext passwords in configuration files. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.ql
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.springframework.org/schema/beans
5+
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
6+
7+
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
8+
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
9+
<property name="url" value="jdbc:mysql://www.example.com:3306/test"/>
10+
<property name="username" value="root"/>
11+
<property name="password" value="mysecret"/>
12+
<property name="initialSize" value="30"/>
13+
14+
<property name="maxActive" value="500"/>
15+
<property name="maxIdle" value="2"/>
16+
<property name="minIdle" value="1"/>
17+
</bean>
18+
19+
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
20+
<property name="dataSource" ref="dataSource"/>
21+
22+
<property name="annotatedClasses">
23+
<list>
24+
<value>com.example.entity.Users</value>
25+
</list>
26+
</property>
27+
28+
<property name="hibernateProperties">
29+
<value>
30+
hibernate.dialect=org.hibernate.dialect.MySQLDialect
31+
hibernate.hbm2ddl.auto=update
32+
hibernate.show_sql=true
33+
hibernate.cache.use_second_level_cache=false
34+
hibernate.cache.provider_class=org.hibernate.cache.internal.NoCacheProvider
35+
hibernate.generate_statistics=true
36+
</value>
37+
</property>
38+
</bean>
39+
</beans>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Context>
3+
<!-- BAD: Password of datasource is in not encrypted -->
4+
<Resource name="jdbc/exampleDS1" auth="Container" type="javax.sql.DataSource"
5+
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
6+
username="root" password="1234"
7+
driverClassName="com.mysql.jdbc.Driver"
8+
url="jdbc:mysql://www.example1.com:3306/proj"/>
9+
10+
<!-- GOOD: Password is encrypted and stored in a password vault -->
11+
<Resource name="jdbc/exampleDS2" auth="Container" type="javax.sql.DataSource"
12+
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
13+
username="root" password="${VAULT::exampleDS2::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0}"
14+
driverClassName="com.mysql.jdbc.Driver"
15+
url="jdbc:mysql://www.example2.com:3306/proj"/>
16+
17+
<!-- GOOD: Password is not stored in the configuration file -->
18+
<Resource name="jdbc/exampleDS3" auth="Container" type="javax.sql.DataSource"
19+
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
20+
username="root" password="${jdbc.password}"
21+
driverClassName="com.mysql.jdbc.Driver"
22+
url="jdbc:mysql://www.example3.com:3306/proj"/>
23+
24+
<!-- GOOD: Password is encrypted -->
25+
<Resource name="jdbc/exampleDS4" auth="Container" type="javax.sql.DataSource"
26+
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
27+
username="root" password="Tg2Nn7wUZOQ6Xc+1lenkZTQ9ZDf9a2/RBRiqJBCIX6o="
28+
driverClassName="com.mysql.jdbc.Driver"
29+
url="jdbc:mysql://www.example4.com:3306/proj"/>
30+
31+
</Context>

0 commit comments

Comments
 (0)