diff --git a/java/CWE-094/CVE-2021-44228.ql b/java/CWE-094/CVE-2021-44228.ql new file mode 100644 index 0000000000..cd8568cc8d --- /dev/null +++ b/java/CWE-094/CVE-2021-44228.ql @@ -0,0 +1,48 @@ +/** + * @name RCE in Log4j CVE-2021-44228 + * @description RCE in Log4j CVE-2021-44228 + * @kind path-problem + * @problem.severity error + * @security-severity 9.9 + * @precision high + * @id java/CVE-2021-44228 + * @tags security + * external/cwe/cwe-094 + */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.dataflow.TaintTracking2 +import DataFlow::PathGraph + +import github.Logging + +class Log4jErrors extends DataFlow::Node { + Log4jErrors() { + exists(MethodAccess ma | + ma.getMethod().getDeclaringType() instanceof Log4jLoggerType and + ( + ma.getMethod().hasName("error") or + ma.getMethod().hasName("info") or + ma.getMethod().hasName("debug") or + ma.getMethod().hasName("trace") or + ma.getMethod().hasName("debugf") or + ma.getMethod().hasName("debugv") + ) and + this.asExpr() = ma.getAnArgument() + ) + } +} + +class Log4jConfig extends TaintTracking::Configuration { + Log4jConfig() { this = "Log4jConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Log4jErrors } +} + +from DataFlow::PathNode source, DataFlow::PathNode sink, Log4jConfig conf +where conf.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Log4j sink", source.getNode(), "user-provided value" diff --git a/java/github/Logging.qll b/java/github/Logging.qll index 728d5d9be2..de5061b9de 100644 --- a/java/github/Logging.qll +++ b/java/github/Logging.qll @@ -24,11 +24,10 @@ class PrintMethods extends LoggingMethodsSinks { // Ref :: https://github.com/github/codeql/blob/main/java/ql/src/experimental/Security/CWE/CWE-532/SensitiveInfoLog.ql // Ref :: https://github.com/github/codeql/blob/main/java/ql/src/experimental/semmle/code/java/Logging.qll#L34 -class LoggerType extends RefType { - LoggerType() { - this.hasQualifiedName("org.apache.log4j", "Category") or // Log4j 1 - this.hasQualifiedName("org.apache.logging.log4j", ["Logger", "LogBuilder"]) or // Log4j 2 - this.hasQualifiedName("org.apache.commons.logging", "Log") or +abstract class LoggerType extends RefType { } + +class StandardLoggersType extends LoggerType { + StandardLoggersType() { // JBoss Logging (`org.jboss.logging.Logger` in some implementations like JBoss Application Server 4.0.4 did not implement `BasicLogger`) this.hasQualifiedName("org.jboss.logging", ["BasicLogger", "Logger"]) or this.hasQualifiedName("org.slf4j.spi", "LoggingEventBuilder") or @@ -41,6 +40,14 @@ class LoggerType extends RefType { } } +class Log4jLoggerType extends LoggerType { + Log4jLoggerType() { + this.hasQualifiedName("org.apache.log4j", "Category") or // Log4j 1 + this.hasQualifiedName("org.apache.logging.log4j", ["Logger", "LogBuilder"]) or // Log4j 2 + this.hasQualifiedName("org.apache.commons.logging", "Log") + } +} + class LoggingMethods extends LoggingMethodsSinks { LoggingMethods() { exists(MethodAccess ma | diff --git a/python/github/HardcodedSecretSinks.qll b/python/github/HardcodedSecretSinks.qll index acb3b8819b..9c0311a2d7 100644 --- a/python/github/HardcodedSecretSinks.qll +++ b/python/github/HardcodedSecretSinks.qll @@ -150,3 +150,22 @@ class PyOtpSink extends CredentialSink { this = API::moduleImport("pyotp").getMember("TOTP").getACall().getArg(1) } } + +class Boto3Sink extends CredentialSink { + Boto3Sink() { + // https://docs.min.io/docs/how-to-use-aws-sdk-for-python-with-minio-server.html + exists(DataFlow::CallCfgNode calls | + // s3 = boto3.resource('s3', + // aws_access_key_id='YOUR-ACCESSKEYID', + // aws_secret_access_key='YOUR-SECRETACCESSKEY' + // aws_session_token="YOUR-SESSION-TOKEN" + // ) + calls = API::moduleImport("boto3").getMember(["client", "resource"]).getACall() and + ( + this = calls.getArgByName("aws_access_key_id") or + this = calls.getArgByName("aws_secret_access_key") or + this = calls.getArgByName("aws_session_token") + ) + ) + } +}