Refactor CommandLineQuery.qll

This commit is contained in:
Ed Minnix
2023-03-19 23:33:02 -04:00
parent 117a983423
commit 0249890747
3 changed files with 37 additions and 9 deletions

View File

@@ -12,9 +12,11 @@ import semmle.code.java.security.ExternalProcess
import semmle.code.java.security.CommandArguments
/**
* DEPRECATED: Use `RemoteUserInputToArgumentToExecFlow` instead.
*
* A taint-tracking configuration for unvalidated user input that is used to run an external process.
*/
class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration {
deprecated class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration {
RemoteUserInputToArgumentToExecFlowConfig() {
this = "ExecCommon::RemoteUserInputToArgumentToExecFlowConfig"
}
@@ -32,13 +34,35 @@ class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configura
}
}
/**
* A taint-tracking configuration for unvalidated user input that is used to run an external process.
*/
private module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec }
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof PrimitiveType
or
node.getType() instanceof BoxedType
or
isSafeCommandArgument(node.asExpr())
}
}
module RemoteUserInputToArgumentToExecFlow =
TaintTracking::Make<RemoteUserInputToArgumentToExecFlowConfig>;
/**
* Implementation of `ExecTainted.ql`. It is extracted to a QLL
* so that it can be excluded from `ExecUnescaped.ql` to avoid
* reporting overlapping results.
*/
predicate execTainted(DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg) {
exists(RemoteUserInputToArgumentToExecFlowConfig conf |
conf.hasFlowPath(source, sink) and sink.getNode() = DataFlow::exprNode(execArg)
)
predicate execTainted(
RemoteUserInputToArgumentToExecFlow::PathNode source,
RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg
) {
RemoteUserInputToArgumentToExecFlow::hasFlowPath(source, sink) and
sink.getNode() = DataFlow::exprNode(execArg)
}

View File

@@ -16,9 +16,11 @@ import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ExternalProcess
import semmle.code.java.security.CommandLineQuery
import DataFlow::PathGraph
import RemoteUserInputToArgumentToExecFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg
from
RemoteUserInputToArgumentToExecFlow::PathNode source,
RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg
where execTainted(source, sink, execArg)
select execArg, source, sink, "This command line depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -17,10 +17,12 @@ import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ExternalProcess
import semmle.code.java.security.CommandLineQuery
import JSchOSInjection
import DataFlow::PathGraph
import RemoteUserInputToArgumentToExecFlow::PathGraph
// This is a clone of query `java/command-line-injection` that also includes experimental sinks.
from DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg
from
RemoteUserInputToArgumentToExecFlow::PathNode source,
RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg
where execTainted(source, sink, execArg)
select execArg, source, sink, "This command line depends on a $@.", source.getNode(),
"user-provided value"