Refactor into separate libraries

This commit is contained in:
Tony Torralba
2021-10-29 17:36:02 +02:00
parent 7f15177498
commit 3ea1af3819
6 changed files with 299 additions and 61 deletions

View File

@@ -92,6 +92,7 @@ private module Frameworks {
private import semmle.code.java.frameworks.JaxWS private import semmle.code.java.frameworks.JaxWS
private import semmle.code.java.frameworks.JoddJson private import semmle.code.java.frameworks.JoddJson
private import semmle.code.java.frameworks.JsonJava private import semmle.code.java.frameworks.JsonJava
private import semmle.code.java.frameworks.Logging
private import semmle.code.java.frameworks.Objects private import semmle.code.java.frameworks.Objects
private import semmle.code.java.frameworks.Optional private import semmle.code.java.frameworks.Optional
private import semmle.code.java.frameworks.Stream private import semmle.code.java.frameworks.Stream

View File

@@ -0,0 +1,237 @@
/** Provides classes and predicates to reason about logging. */
import java
import semmle.code.java.dataflow.ExternalFlow
private class LoggingSummaryModels extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.logging.log4j;Logger;true;entry;(Object[]);;Argument[0];ReturnValue;taint",
"org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint",
"org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint",
"org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier);;Argument[0..1];ReturnValue;taint",
"org.apache.logging.log4j;Logger;true;traceEntry;(Supplier);;Argument[0];ReturnValue;taint",
"org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value",
"org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value",
"org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value",
"org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value",
"org.slf4j.spi.LoggingEventBuilder;true;addArgument;;;Argument[1];Argument[-1];taint",
"org.slf4j.spi.LoggingEventBuilder;true;addArgument;;;Argument[-1];ReturnValue;value",
"org.slf4j.spi.LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[-1];taint",
"org.slf4j.spi.LoggingEventBuilder;true;addKeyValue;;;Argument[-1];ReturnValue;value",
"org.slf4j.spi.LoggingEventBuilder;true;addMarker;;;Argument[-1];ReturnValue;value",
"org.slf4j.spi.LoggingEventBuilder;true;setCause;;;Argument[-1];ReturnValue;value",
"java.util.logging;LogRecord;false;LogRecord;;;Argument[1];Argument[-1];taint"
]
}
}
private string jBossLogger() { result = "org.jboss.logging;" + ["BasicLogger", "Logger"] }
private class LoggingSinkModels extends SinkModelCsv {
override predicate row(string row) {
row =
[
// org.apache.log4j.Category
"org.apache.log4j;Category;true;assertLog;;;Argument[1];logging",
"org.apache.log4j;Category;true;debug;;;Argument[0];logging",
"org.apache.log4j;Category;true;error;;;Argument[0];logging",
"org.apache.log4j;Category;true;fatal;;;Argument[0];logging",
"org.apache.log4j;Category;true;forcedLog;;;Argument[2];logging",
"org.apache.log4j;Category;true;info;;;Argument[0];logging",
"org.apache.log4j;Category;true;l7dlog;(Priority,String,Object[],Throwable);;Argument[2];logging",
"org.apache.log4j;Category;true;log;(Priority,Object);;Argument[1];logging",
"org.apache.log4j;Category;true;log;(String,Priority,Object,Throwable);;Argument[2];logging",
"org.apache.log4j;Category;true;warn;;;Argument[0];logging",
// org.apache.logging.log4j.Logger
"org.apache.logging.log4j;Logger;true;" +
[["debug", "error", "fatal", "info", "trace", "warn"] + ";(", "log;(Level,"] +
[
"CharSequence);;Argument[0];logging", "CharSequence,Throwable);;Argument[0];logging",
"Marker,CharSequence);;Argument[1];logging",
"Marker,CharSequence,Throwable);;Argument[1];logging",
"Marker,Message);;Argument[1];logging", "Marker,MessageSupplier);;Argument[1];logging",
"Marker,MessageSupplier,Throwable);;Argument[1];logging",
"Marker,Object);;Argument[1];logging", "Marker,Object,Throwable);;Argument[1];logging",
"Marker,String);;Argument[1];logging",
"Marker,String,Object[]);;Argument[1..2];logging",
"Marker,String,Object);;Argument[1..2];logging",
"Marker,String,Object,Object);;Argument[1..3];logging",
"Marker,String,Object,Object,Object);;Argument[1..4];logging",
"Marker,String,Object,Object,Object,Object);;Argument[1..5];logging",
"Marker,String,Object,Object,Object,Object,Object);;Argument[1..6];logging",
"Marker,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging",
"Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging",
"Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging",
"Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging",
"Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];logging",
"Marker,String,Supplier);;Argument[1..2];logging",
"Marker,String,Throwable);;Argument[1];logging",
"Marker,Supplier);;Argument[1];logging",
"Marker,Supplier,Throwable);;Argument[1];logging", ";(Message);;Argument[0];logging",
"MessageSupplier);;Argument[0];logging",
"MessageSupplier,Throwable);;Argument[0];logging",
"Message,Throwable);;Argument[0];logging", ";(Object);;Argument[0];logging",
"Object,Throwable);;Argument[0];logging", ";(String);;Argument[0];logging",
"String,Object[]);;Argument[0..1];logging", "String,Object);;Argument[0..1];logging",
"String,Object,Object);;Argument[0..2];logging",
"String,Object,Object,Object);;Argument[0..3];logging",
"String,Object,Object,Object,Object);;Argument[0..4];logging",
"String,Object,Object,Object,Object,Object);;Argument[0..5];logging",
"String,Object,Object,Object,Object,Object,Object);;Argument[0..6];logging",
"String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];logging",
"String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];logging",
"String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];logging",
"String,Supplier);;Argument[0..1];logging", "String,Throwable);;Argument[0];logging",
"Supplier);;Argument[0];logging", "Supplier,Throwable);;Argument[0];logging"
], "org.apache.logging.log4j;Logger;true;entry;(Object[]);;Argument[0];logging",
"org.apache.logging.log4j;Logger;true;logMessage;(Level,Marker,String,StackTraceElement,Message,Throwable);;Argument[4];logging",
"org.apache.logging.log4j;Logger;true;printf;(Level,Marker,String,Object[]);;Argument[2..3];logging",
"org.apache.logging.log4j;Logger;true;printf;(Level,String,Object[]);;Argument[1..2];logging",
"org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];logging",
"org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];logging",
"org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier);;Argument[0..1];logging",
"org.apache.logging.log4j;Logger;true;traceEntry;(Supplier);;Argument[0];logging",
"org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage);;Argument[0];logging",
"org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[0..1];logging",
"org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[0..1];logging",
"org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];logging",
"org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[0..1];logging",
// org.apache.logging.log4j.LogBuilder
"org.apache.logging.log4j;LogBuilder;true;log;(CharSequence);;Argument[0];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(Message);;Argument[0];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(Object);;Argument[0];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String);;Argument[0];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object[]);;Argument[0..1];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object);;Argument[0..1];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object);;Argument[0..2];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object);;Argument[0..3];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object);;Argument[0..4];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object);;Argument[0..5];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(String,Supplier);;Argument[0..1];logging",
"org.apache.logging.log4j;LogBuilder;true;log;(Supplier);;Argument[0];logging",
// org.apache.commons.logging.Log
"org.apache.commons.logging;Log;true;" +
["debug", "error", "fatal", "info", "trace", "warn"] + ";;;Argument[0];logging",
// org.jboss.logging.BasicLogger and org.jboss.logging.Logger
// (org.jboss.logging.Logger does not implement BasicLogger in some implementations like JBoss Application Server 4.0.4)
jBossLogger() + ";true;" +
[["debug", "error", "fatal", "info", "trace", "warn"] + ";(", "log;(Level,"] +
[
"Object);;Argument[0];logging", ";(Object,Object[]);;Argument[0..1];logging",
"Object,Object[],Throwable);;Argument[0..1];logging",
"Object,Throwable);;Argument[0];logging",
"String,Object,Object[],Throwable);;Argument[1..2];logging",
"String,Object,Throwable);;Argument[1];logging"
],
jBossLogger() + ";true;log;(String,Level,Object,Object[],Throwable);;Argument[2..3];logging",
jBossLogger() + ";true;" +
[
["debug", "error", "fatal", "info", "trace", "warn"] + ["f", "v"] + ";(",
"log" + ["f", "v"] + ";(Level,"
] +
[
"String,Object[]);;Argument[0..1];logging", "String,Object);;Argument[0..1];logging",
"String,Object,Object);;Argument[0..2];logging",
"String,Object,Object,Object);;Argument[0..3];logging",
"String,Object,Object,Object,Object);;Argument[0..4];logging",
"Throwable,String,Object);;Argument[1..2];logging",
"Throwable,String,Object,Object);;Argument[1..3];logging",
"Throwable,String,Object,Object,Object);;Argument[0..4];logging",
],
jBossLogger() + ";true;log" + ["f", "v"] +
[
";(String,Level,Throwable,String,Object[]);;Argument[3..4];logging",
";(String,Level,Throwable,String,Object);;Argument[3..4];logging",
";(String,Level,Throwable,String,Object,Object);;Argument[3..5];logging",
";(String,Level,Throwable,String,Object,Object,Object);;Argument[3..6];logging"
],
// org.slf4j.spi.LoggingEventBuilder
"org.slf4j.spi;LoggingEventBuilder;true;log;;;Argument[0];logging",
"org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object);;Argument[1];logging",
"org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object[]);;Argument[1];logging",
"org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object,Object);;Argument[1..2];logging",
"org.slf4j;Logger;true;" + ["debug", "error", "info", "trace", "warn"] +
[
";(String);;Argument[0];logging", ";(String,Object);;Argument[0..1];logging",
";(String,Object[]);;Argument[0..1];logging",
";(String,Object,Object);;Argument[0..2];logging",
";(String,Throwable);;Argument[0];logging", ";(Marker,String);;Argument[1];logging",
";(Marker,String,Object);;Argument[1..2];logging",
";(Marker,String,Object[]);;Argument[1..2];logging",
";(Marker,String,Object[],Object);;Argument[1..3];logging",
";(Marker,String,Object[],Object,Object);;Argument[1..4];logging"
],
// org.slf4j.Logger
"org.scijava.log;Logger;true;alwaysLog;(int,Object,Throwable);;Argument[1];logging",
"org.scijava.log;Logger;true;" +
[["debug", "error", "info", "trace", "warn"] + ";(", "log;(int,"] +
["Object);;Argument[0];logging", "Object,Throwable);;Argument[0];logging"],
// com.google.common.flogger.LoggingApi
"com.google.common.flogger;LoggingApi;true;log;" +
[
";;;Argument[0];logging", "(String,Object);;Argument[1]",
"(String,Object,Object);;Argument[1..2]",
"(String,Object,Object,Object);;Argument[1..3]", "(String,Object,boolean);;Argument[1]",
"(String,Object,char);;Argument[1]", "(String,Object,byte);;Argument[1]",
"(String,Object,short);;Argument[1]", "(String,Object,int);;Argument[1]",
"(String,Object,long);;Argument[1]", "(String,Object,float);;Argument[1]",
"(String,Object,double);;Argument[1]", "(String,boolean,Object);;Argument[2]",
"(String,char,Object);;Argument[2]", "(String,byte,Object);;Argument[2]",
"(String,short,Object);;Argument[2]", "(String,int,Object);;Argument[2]",
"(String,long,Object);;Argument[2]", "(String,float,Object);;Argument[2]",
"(String,double,Object);;Argument[2]"
] + ";logging",
// java.lang.System$Logger
"java.lang;System$Logger;true;log;" +
[
"(Level,Object);;Argument[1]", "(Level,String);;Argument[1]",
"(Level,String,Object[]);;Argument[1..2]", "(Level,String,Throwable);;Argument[1]",
"(Level,String,Supplier);;Argument[1..2]",
"(Level,String,Supplier,Throwable);;Argument[1..2]",
"(Level,ResourceBundle,String,Object[]);;Argument[2..3]",
"(Level,ResourceBundle,String,Throwable);;Argument[2]"
] + ";logging",
// java.util.logging.Logger
"java.util.logging;Logger;true;" +
["config", "fine", "finer", "finest", "info", "severe", "warning"] +
";;;Argument[0];logging",
"java.util.logging;Logger;true;entering;(String,String);;Argument[0..1];logging",
"java.util.logging;Logger;true;entering;(String,String,Object);;Argument[0..2];logging",
"java.util.logging;Logger;true;entering;(String,String,Object[]);;Argument[0..2];logging",
"java.util.logging;Logger;true;exiting;(String,String);;Argument[0..1];logging",
"java.util.logging;Logger;true;exiting;(String,String,Object);;Argument[0..2];logging",
"java.util.logging;Logger;true;log;(Level,String);;Argument[1];logging",
"java.util.logging;Logger;true;log;(Level,String,Object);;Argument[1..2];logging",
"java.util.logging;Logger;true;log;(Level,String,Object[]);;Argument[1..2];logging",
"java.util.logging;Logger;true;log;(Level,String,Throwable);;Argument[1];logging",
"java.util.logging;Logger;true;log;(Level,Supplier);;Argument[1];logging",
"java.util.logging;Logger;true;log;(Level,Throwable,Supplier);;Argument[2];logging",
"java.util.logging;Logger;true;log;(LogRecord);;Argument[1];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,String);;Argument[1..3];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,String,Object);;Argument[1..4];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,String,Object[]);;Argument[1..4];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,String,Object[]);;Argument[1..4];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,String,Throwable);;Argument[1..3];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,Supplier);;Argument[1..3];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,Throwable,Supplier);;Argument[1..2];logging",
"java.util.logging;Logger;true;logp;(Level,String,String,Throwable,Supplier);;Argument[4];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Object[]);;Argument[1..2];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Object[]);;Argument[4..5];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Throwable);;Argument[1..2];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Throwable);;Argument[3];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,String,String);;Argument[1..4];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Object);;Argument[1..5];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Object[]);;Argument[1..5];logging",
"java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Throwable);;Argument[1..4];logging",
// android.util.Log
"android.util;Log;true;" + ["d", "v", "i", "w", "e", "wtf"] + ";;;Argument[1];logging"
]
}
}

View File

@@ -0,0 +1,36 @@
/** Provides classes and predicates related to Log Injection vulnerabilities. */
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.ExternalFlow
/** A data flow sink for unvalidated user input that is used to log messages. */
abstract class LogInjectionSink extends DataFlow::Node { }
/**
* A node that sanitizes a message before logging to avoid log injection.
*/
abstract class LogInjectionSanitizer extends DataFlow::Node { }
/**
* A unit class for adding additional taint steps.
*
* Extend this class to add additional taint steps that should apply to the `LogInjectionConfiguration`.
*/
class LogInjectionAdditionalTaintStep extends Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for the `LogInjectionConfiguration` configuration.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
private class DefaultLogInjectionSink extends LogInjectionSink {
DefaultLogInjectionSink() { sinkNode(this, "logging") }
}
private class DefaultLogInjectionSanitizer extends LogInjectionSanitizer {
DefaultLogInjectionSanitizer() {
this.getType() instanceof BoxedType or this.getType() instanceof PrimitiveType
}
}

View File

@@ -0,0 +1,22 @@
/** Provides taint tracking configurations to be used in queries related to the Log Injection vulnerability. */
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.LogInjection
/**
* A taint-tracking configuration for tracking untrusted user input used in log entries.
*/
class LogInjectionConfiguration extends TaintTracking::Configuration {
LogInjectionConfiguration() { this = "Log Injection" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof LogInjectionSink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof LogInjectionSanitizer }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
any(LogInjectionAdditionalTaintStep c).step(node1, node2)
}
}

View File

@@ -11,28 +11,10 @@
*/ */
import java import java
import semmle.code.java.security.LogInjectionQuery
import DataFlow::PathGraph import DataFlow::PathGraph
import experimental.semmle.code.java.Logging
import semmle.code.java.dataflow.FlowSources
/**
* A taint-tracking configuration for tracking untrusted user input used in log entries.
*/
private class LogInjectionConfiguration extends TaintTracking::Configuration {
LogInjectionConfiguration() { this = "Log Injection" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(LoggingCall c).getALogArgument()
}
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof BoxedType or node.getType() instanceof PrimitiveType
}
}
from LogInjectionConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink from LogInjectionConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink) where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to log entry.", source.getNode(), select sink.getNode(), source, sink, "This $@ flows to a log entry.", source.getNode(),
"User-provided value" "user-provided value"

View File

@@ -1,40 +0,0 @@
/**
* Provides classes and predicates for working with loggers.
*/
import java
/** Models a call to a logging method. */
class LoggingCall extends MethodAccess {
LoggingCall() {
exists(RefType t, Method m |
t.hasQualifiedName("org.apache.log4j", "Category") or // Log4j 1
t.hasQualifiedName("org.apache.logging.log4j", ["Logger", "LogBuilder"]) or // Log4j 2
t.hasQualifiedName("org.apache.commons.logging", "Log") or
// JBoss Logging (`org.jboss.logging.Logger` in some implementations like JBoss Application Server 4.0.4 did not implement `BasicLogger`)
t.hasQualifiedName("org.jboss.logging", ["BasicLogger", "Logger"]) or
t.hasQualifiedName("org.slf4j.spi", "LoggingEventBuilder") or
t.hasQualifiedName("org.slf4j", "Logger") or
t.hasQualifiedName("org.scijava.log", "Logger") or
t.hasQualifiedName("com.google.common.flogger", "LoggingApi") or
t.hasQualifiedName("java.lang", "System$Logger") or
t.hasQualifiedName("java.util.logging", "Logger")
|
(
m.getDeclaringType().getASourceSupertype*() = t or
m.getDeclaringType().extendsOrImplements*(t)
) and
m.getReturnType() instanceof VoidType and
this = m.getAReference()
)
or
exists(RefType t, Method m | t.hasQualifiedName("android.util", "Log") |
m.hasName(["d", "e", "i", "v", "w", "wtf"]) and
m.getDeclaringType() = t and
this = m.getAReference()
)
}
/** Returns an argument which would be logged by this call. */
Argument getALogArgument() { result = this.getArgument(_) }
}