Skip to content

Commit 8c6d58e

Browse files
committed
Refactored into libraries
1 parent 0e149f0 commit 8c6d58e

File tree

3 files changed

+104
-87
lines changed

3 files changed

+104
-87
lines changed

java/ql/src/Security/CWE/CWE-297/InsecureJavaMail.ql

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -12,96 +12,12 @@
1212
*/
1313

1414
import java
15-
16-
/**
17-
* The method to set Java properties
18-
*/
19-
class SetPropertyMethod extends Method {
20-
SetPropertyMethod() {
21-
this.hasName("setProperty") and
22-
this.getDeclaringType().hasQualifiedName("java.util", "Properties")
23-
or
24-
this.hasName("put") and
25-
this.getDeclaringType().getASourceSupertype*().hasQualifiedName("java.util", "Dictionary")
26-
}
27-
}
28-
29-
/**
30-
* The insecure way to set Java properties in mail sessions.
31-
* 1. Set the mail.smtp.auth property to provide the SMTP Transport with a username and password when connecting to the SMTP server or
32-
* set the mail.smtp.ssl.socketFactory/mail.smtp.ssl.socketFactory.class property to create an SMTP SSL socket.
33-
* 2. No mail.smtp.ssl.checkserveridentity property is enabled.
34-
*/
35-
predicate isInsecureMailPropertyConfig(VarAccess propertiesVarAccess) {
36-
exists(MethodAccess ma |
37-
ma.getMethod() instanceof SetPropertyMethod and
38-
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess() and
39-
(
40-
getStringValue(ma.getArgument(0)).matches("%.auth%") and //mail.smtp.auth
41-
getStringValue(ma.getArgument(1)) = "true"
42-
or
43-
getStringValue(ma.getArgument(0)).matches("%.socketFactory%") //mail.smtp.socketFactory or mail.smtp.socketFactory.class
44-
)
45-
) and
46-
not exists(MethodAccess ma |
47-
ma.getMethod() instanceof SetPropertyMethod and
48-
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess() and
49-
(
50-
getStringValue(ma.getArgument(0)).matches("%.ssl.checkserveridentity%") and //mail.smtp.ssl.checkserveridentity
51-
getStringValue(ma.getArgument(1)) = "true"
52-
)
53-
)
54-
}
55-
56-
/**
57-
* Helper method to get string value of an argument
58-
*/
59-
string getStringValue(Expr expr) {
60-
result = expr.(CompileTimeConstantExpr).getStringValue()
61-
or
62-
result = getStringValue(expr.(AddExpr).getLeftOperand())
63-
or
64-
result = getStringValue(expr.(AddExpr).getRightOperand())
65-
}
66-
67-
/**
68-
* The JavaMail session class `javax.mail.Session`
69-
*/
70-
class MailSession extends RefType {
71-
MailSession() { this.hasQualifiedName("javax.mail", "Session") }
72-
}
73-
74-
/**
75-
* The class of Apache SimpleMail
76-
*/
77-
class SimpleMail extends RefType {
78-
SimpleMail() { this.hasQualifiedName("org.apache.commons.mail", "SimpleEmail") }
79-
}
80-
81-
/**
82-
* Has TLS/SSL enabled with SimpleMail
83-
*/
84-
predicate enableTLSWithSimpleMail(MethodAccess ma) {
85-
ma.getMethod().hasName("setSSLOnConnect") and
86-
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
87-
}
88-
89-
/**
90-
* Has no certificate check
91-
*/
92-
predicate hasNoCertCheckWithSimpleMail(VarAccess va) {
93-
not exists(MethodAccess ma |
94-
ma.getQualifier() = va.getVariable().getAnAccess() and
95-
ma.getMethod().hasName("setSSLCheckServerIdentity") and
96-
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
97-
)
98-
}
15+
import semmle.code.java.security.Mail
9916

10017
from MethodAccess ma
10118
where
102-
ma.getMethod().getDeclaringType() instanceof MailSession and
103-
ma.getMethod().getName() = "getInstance" and
19+
ma.getMethod() instanceof MailSessionGetInstanceMethod and
10420
isInsecureMailPropertyConfig(ma.getArgument(0))
10521
or
106-
enableTLSWithSimpleMail(ma) and hasNoCertCheckWithSimpleMail(ma.getQualifier())
22+
enablesEmailSsl(ma) and not hasSslCertificateCheck(ma.getQualifier())
10723
select ma, "Java mailing has insecure SSL configuration"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/** Provides classes and predicates to work with email */
2+
3+
import java
4+
5+
/**
6+
* The class `javax.mail.Session`
7+
*/
8+
class MailSession extends Class {
9+
MailSession() { this.hasQualifiedName("javax.mail", "Session") }
10+
}
11+
12+
/**
13+
* The method `getInstance` of the class `javax.mail.Session`
14+
*/
15+
class MailSessionGetInstanceMethod extends Method {
16+
MailSessionGetInstanceMethod() {
17+
this.getDeclaringType() instanceof MailSession and
18+
this.getName() = "getInstance"
19+
}
20+
}
21+
22+
/**
23+
* A subtype of the class `org.apache.commons.mail.Mail`
24+
*/
25+
class ApacheEmail extends Class {
26+
ApacheEmail() { this.getASupertype*().hasQualifiedName("org.apache.commons.mail", "Email") }
27+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/** Provides classes and predicates to reason about email vulnerabilities. */
2+
3+
import java
4+
import semmle.code.java.frameworks.Mail
5+
private import semmle.code.java.frameworks.Properties
6+
7+
/**
8+
* The insecure way to set Java properties in mail sessions.
9+
* 1. Set the `mail.smtp.auth` property to provide the SMTP Transport with a username and password when connecting to the SMTP server or
10+
* set the `mail.smtp.ssl.socketFactory`/`mail.smtp.ssl.socketFactory.class` property to create an SMTP SSL socket.
11+
* 2. No `mail.smtp.ssl.checkserveridentity` property is enabled.
12+
*/
13+
predicate isInsecureMailPropertyConfig(VarAccess propertiesVarAccess) {
14+
exists(MethodAccess ma |
15+
ma.getMethod() instanceof SetPropertyMethod and
16+
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess()
17+
|
18+
getStringValue(ma.getArgument(0)).matches("%.auth%") and //mail.smtp.auth
19+
getStringValue(ma.getArgument(1)) = "true"
20+
or
21+
getStringValue(ma.getArgument(0)).matches("%.socketFactory%") //mail.smtp.socketFactory or mail.smtp.socketFactory.class
22+
) and
23+
not exists(MethodAccess ma |
24+
ma.getMethod() instanceof SetPropertyMethod and
25+
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess()
26+
|
27+
getStringValue(ma.getArgument(0)).matches("%.ssl.checkserveridentity%") and //mail.smtp.ssl.checkserveridentity
28+
getStringValue(ma.getArgument(1)) = "true"
29+
)
30+
}
31+
32+
/**
33+
* Holds if `ma` enables TLS/SSL with Apache Email.
34+
*/
35+
predicate enablesEmailSsl(MethodAccess ma) {
36+
ma.getMethod().hasName("setSSLOnConnect") and
37+
ma.getMethod().getDeclaringType() instanceof ApacheEmail and
38+
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
39+
}
40+
41+
/**
42+
* Holds if a SSL certificate check is enabled on `va` with Apache Email
43+
*/
44+
predicate hasSslCertificateCheck(VarAccess va) {
45+
exists(MethodAccess ma |
46+
ma.getQualifier() = va.getVariable().getAnAccess() and
47+
ma.getMethod().hasName("setSSLCheckServerIdentity") and
48+
ma.getMethod().getDeclaringType() instanceof ApacheEmail and
49+
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
50+
)
51+
}
52+
53+
/**
54+
* Helper method to get string value of an argument
55+
*/
56+
private string getStringValue(Expr expr) {
57+
result = expr.(CompileTimeConstantExpr).getStringValue()
58+
or
59+
result = getStringValue(expr.(AddExpr).getLeftOperand())
60+
or
61+
result = getStringValue(expr.(AddExpr).getRightOperand())
62+
}
63+
64+
/**
65+
* A method to set Java properties
66+
*/
67+
private class SetPropertyMethod extends Method {
68+
SetPropertyMethod() {
69+
this instanceof PropertiesSetPropertyMethod
70+
or
71+
this.hasName("put") and
72+
this.getDeclaringType().getASourceSupertype*().hasQualifiedName("java.util", "Dictionary")
73+
}
74+
}

0 commit comments

Comments
 (0)