mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Refactored into libraries
This commit is contained in:
@@ -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"
|
||||
|
||||
27
java/ql/src/semmle/code/java/frameworks/Mail.qll
Normal file
27
java/ql/src/semmle/code/java/frameworks/Mail.qll
Normal 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") }
|
||||
}
|
||||
74
java/ql/src/semmle/code/java/security/Mail.qll
Normal file
74
java/ql/src/semmle/code/java/security/Mail.qll
Normal 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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user