Refactored into libraries

This commit is contained in:
Tony Torralba
2021-06-18 11:11:52 +02:00
parent 0e149f0523
commit 8c6d58e6d8
3 changed files with 104 additions and 87 deletions

View File

@@ -12,96 +12,12 @@
*/
import java
/**
* The method to set Java properties
*/
class SetPropertyMethod extends Method {
SetPropertyMethod() {
this.hasName("setProperty") and
this.getDeclaringType().hasQualifiedName("java.util", "Properties")
or
this.hasName("put") and
this.getDeclaringType().getASourceSupertype*().hasQualifiedName("java.util", "Dictionary")
}
}
/**
* The insecure way to set Java properties in mail sessions.
* 1. Set the mail.smtp.auth property to provide the SMTP Transport with a username and password when connecting to the SMTP server or
* set the mail.smtp.ssl.socketFactory/mail.smtp.ssl.socketFactory.class property to create an SMTP SSL socket.
* 2. No mail.smtp.ssl.checkserveridentity property is enabled.
*/
predicate isInsecureMailPropertyConfig(VarAccess propertiesVarAccess) {
exists(MethodAccess ma |
ma.getMethod() instanceof SetPropertyMethod and
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess() and
(
getStringValue(ma.getArgument(0)).matches("%.auth%") and //mail.smtp.auth
getStringValue(ma.getArgument(1)) = "true"
or
getStringValue(ma.getArgument(0)).matches("%.socketFactory%") //mail.smtp.socketFactory or mail.smtp.socketFactory.class
)
) and
not exists(MethodAccess ma |
ma.getMethod() instanceof SetPropertyMethod and
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess() and
(
getStringValue(ma.getArgument(0)).matches("%.ssl.checkserveridentity%") and //mail.smtp.ssl.checkserveridentity
getStringValue(ma.getArgument(1)) = "true"
)
)
}
/**
* Helper method to get string value of an argument
*/
string getStringValue(Expr expr) {
result = expr.(CompileTimeConstantExpr).getStringValue()
or
result = getStringValue(expr.(AddExpr).getLeftOperand())
or
result = getStringValue(expr.(AddExpr).getRightOperand())
}
/**
* The JavaMail session class `javax.mail.Session`
*/
class MailSession extends RefType {
MailSession() { this.hasQualifiedName("javax.mail", "Session") }
}
/**
* The class of Apache SimpleMail
*/
class SimpleMail extends RefType {
SimpleMail() { this.hasQualifiedName("org.apache.commons.mail", "SimpleEmail") }
}
/**
* Has TLS/SSL enabled with SimpleMail
*/
predicate enableTLSWithSimpleMail(MethodAccess ma) {
ma.getMethod().hasName("setSSLOnConnect") and
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
}
/**
* Has no certificate check
*/
predicate hasNoCertCheckWithSimpleMail(VarAccess va) {
not exists(MethodAccess ma |
ma.getQualifier() = va.getVariable().getAnAccess() and
ma.getMethod().hasName("setSSLCheckServerIdentity") and
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
)
}
import semmle.code.java.security.Mail
from MethodAccess ma
where
ma.getMethod().getDeclaringType() instanceof MailSession and
ma.getMethod().getName() = "getInstance" and
ma.getMethod() instanceof MailSessionGetInstanceMethod and
isInsecureMailPropertyConfig(ma.getArgument(0))
or
enableTLSWithSimpleMail(ma) and hasNoCertCheckWithSimpleMail(ma.getQualifier())
enablesEmailSsl(ma) and not hasSslCertificateCheck(ma.getQualifier())
select ma, "Java mailing has insecure SSL configuration"

View File

@@ -0,0 +1,27 @@
/** Provides classes and predicates to work with email */
import java
/**
* The class `javax.mail.Session`
*/
class MailSession extends Class {
MailSession() { this.hasQualifiedName("javax.mail", "Session") }
}
/**
* The method `getInstance` of the class `javax.mail.Session`
*/
class MailSessionGetInstanceMethod extends Method {
MailSessionGetInstanceMethod() {
this.getDeclaringType() instanceof MailSession and
this.getName() = "getInstance"
}
}
/**
* A subtype of the class `org.apache.commons.mail.Mail`
*/
class ApacheEmail extends Class {
ApacheEmail() { this.getASupertype*().hasQualifiedName("org.apache.commons.mail", "Email") }
}

View File

@@ -0,0 +1,74 @@
/** Provides classes and predicates to reason about email vulnerabilities. */
import java
import semmle.code.java.frameworks.Mail
private import semmle.code.java.frameworks.Properties
/**
* The insecure way to set Java properties in mail sessions.
* 1. Set the `mail.smtp.auth` property to provide the SMTP Transport with a username and password when connecting to the SMTP server or
* set the `mail.smtp.ssl.socketFactory`/`mail.smtp.ssl.socketFactory.class` property to create an SMTP SSL socket.
* 2. No `mail.smtp.ssl.checkserveridentity` property is enabled.
*/
predicate isInsecureMailPropertyConfig(VarAccess propertiesVarAccess) {
exists(MethodAccess ma |
ma.getMethod() instanceof SetPropertyMethod and
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess()
|
getStringValue(ma.getArgument(0)).matches("%.auth%") and //mail.smtp.auth
getStringValue(ma.getArgument(1)) = "true"
or
getStringValue(ma.getArgument(0)).matches("%.socketFactory%") //mail.smtp.socketFactory or mail.smtp.socketFactory.class
) and
not exists(MethodAccess ma |
ma.getMethod() instanceof SetPropertyMethod and
ma.getQualifier() = propertiesVarAccess.getVariable().getAnAccess()
|
getStringValue(ma.getArgument(0)).matches("%.ssl.checkserveridentity%") and //mail.smtp.ssl.checkserveridentity
getStringValue(ma.getArgument(1)) = "true"
)
}
/**
* Holds if `ma` enables TLS/SSL with Apache Email.
*/
predicate enablesEmailSsl(MethodAccess ma) {
ma.getMethod().hasName("setSSLOnConnect") and
ma.getMethod().getDeclaringType() instanceof ApacheEmail and
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
}
/**
* Holds if a SSL certificate check is enabled on `va` with Apache Email
*/
predicate hasSslCertificateCheck(VarAccess va) {
exists(MethodAccess ma |
ma.getQualifier() = va.getVariable().getAnAccess() and
ma.getMethod().hasName("setSSLCheckServerIdentity") and
ma.getMethod().getDeclaringType() instanceof ApacheEmail and
ma.getArgument(0).(BooleanLiteral).getBooleanValue() = true
)
}
/**
* Helper method to get string value of an argument
*/
private string getStringValue(Expr expr) {
result = expr.(CompileTimeConstantExpr).getStringValue()
or
result = getStringValue(expr.(AddExpr).getLeftOperand())
or
result = getStringValue(expr.(AddExpr).getRightOperand())
}
/**
* A method to set Java properties
*/
private class SetPropertyMethod extends Method {
SetPropertyMethod() {
this instanceof PropertiesSetPropertyMethod
or
this.hasName("put") and
this.getDeclaringType().getASourceSupertype*().hasQualifiedName("java.util", "Dictionary")
}
}