mirror of
https://github.com/github/codeql.git
synced 2025-12-23 20:26:32 +01:00
C++: Update UnsafeCreateProcessCall with DataFlow::ConfigSig
This commit is contained in:
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.ir.dataflow.DataFlow
|
import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
import semmle.code.cpp.ir.dataflow.DataFlow2
|
|
||||||
|
|
||||||
predicate isCreateProcessFunction(FunctionCall call, int applicationNameIndex, int commandLineIndex) {
|
predicate isCreateProcessFunction(FunctionCall call, int applicationNameIndex, int commandLineIndex) {
|
||||||
call.getTarget().hasGlobalName("CreateProcessA") and
|
call.getTarget().hasGlobalName("CreateProcessA") and
|
||||||
@@ -55,42 +54,40 @@ class CreateProcessFunctionCall extends FunctionCall {
|
|||||||
/**
|
/**
|
||||||
* Dataflow that detects a call to CreateProcess with a NULL value for lpApplicationName argument
|
* Dataflow that detects a call to CreateProcess with a NULL value for lpApplicationName argument
|
||||||
*/
|
*/
|
||||||
class NullAppNameCreateProcessFunctionConfiguration extends DataFlow::Configuration {
|
module NullAppNameCreateProcessFunctionConfiguration implements DataFlow::ConfigSig {
|
||||||
NullAppNameCreateProcessFunctionConfiguration() {
|
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof NullValue }
|
||||||
this = "NullAppNameCreateProcessFunctionConfiguration"
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof NullValue }
|
predicate isSink(DataFlow::Node sink) {
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) {
|
|
||||||
exists(CreateProcessFunctionCall call, Expr val | val = sink.asExpr() |
|
exists(CreateProcessFunctionCall call, Expr val | val = sink.asExpr() |
|
||||||
val = call.getArgument(call.getApplicationNameArgumentId())
|
val = call.getArgument(call.getApplicationNameArgumentId())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module NullAppNameCreateProcessFunction =
|
||||||
|
DataFlow::Make<NullAppNameCreateProcessFunctionConfiguration>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dataflow that detects a call to CreateProcess with an unquoted commandLine argument
|
* Dataflow that detects a call to CreateProcess with an unquoted commandLine argument
|
||||||
*/
|
*/
|
||||||
class QuotedCommandInCreateProcessFunctionConfiguration extends DataFlow2::Configuration {
|
module QuotedCommandInCreateProcessFunctionConfiguration implements DataFlow::ConfigSig {
|
||||||
QuotedCommandInCreateProcessFunctionConfiguration() {
|
predicate isSource(DataFlow::Node source) {
|
||||||
this = "QuotedCommandInCreateProcessFunctionConfiguration"
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate isSource(DataFlow2::Node source) {
|
|
||||||
exists(string s |
|
exists(string s |
|
||||||
s = source.asExpr().getValue().toString() and
|
s = source.asExpr().getValue().toString() and
|
||||||
not isQuotedOrNoSpaceApplicationNameOnCmd(s)
|
not isQuotedOrNoSpaceApplicationNameOnCmd(s)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isSink(DataFlow2::Node sink) {
|
predicate isSink(DataFlow::Node sink) {
|
||||||
exists(CreateProcessFunctionCall call, Expr val | val = sink.asExpr() |
|
exists(CreateProcessFunctionCall call, Expr val | val = sink.asExpr() |
|
||||||
val = call.getArgument(call.getCommandLineArgumentId())
|
val = call.getArgument(call.getCommandLineArgumentId())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module QuotedCommandInCreateProcessFunction =
|
||||||
|
DataFlow::Make<QuotedCommandInCreateProcessFunctionConfiguration>;
|
||||||
|
|
||||||
bindingset[s]
|
bindingset[s]
|
||||||
predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {
|
predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {
|
||||||
s.regexpMatch("\"([^\"])*\"[\\s\\S]*") // The first element (path) is quoted
|
s.regexpMatch("\"([^\"])*\"[\\s\\S]*") // The first element (path) is quoted
|
||||||
@@ -100,14 +97,14 @@ predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {
|
|||||||
|
|
||||||
from CreateProcessFunctionCall call, string msg1, string msg2
|
from CreateProcessFunctionCall call, string msg1, string msg2
|
||||||
where
|
where
|
||||||
exists(Expr appName, NullAppNameCreateProcessFunctionConfiguration nullAppConfig |
|
exists(Expr appName |
|
||||||
appName = call.getArgument(call.getApplicationNameArgumentId()) and
|
appName = call.getArgument(call.getApplicationNameArgumentId()) and
|
||||||
nullAppConfig.hasFlowToExpr(appName) and
|
NullAppNameCreateProcessFunction::hasFlowToExpr(appName) and
|
||||||
msg1 = call.toString() + " with lpApplicationName == NULL (" + appName + ")"
|
msg1 = call.toString() + " with lpApplicationName == NULL (" + appName + ")"
|
||||||
) and
|
) and
|
||||||
exists(Expr cmd, QuotedCommandInCreateProcessFunctionConfiguration quotedConfig |
|
exists(Expr cmd |
|
||||||
cmd = call.getArgument(call.getCommandLineArgumentId()) and
|
cmd = call.getArgument(call.getCommandLineArgumentId()) and
|
||||||
quotedConfig.hasFlowToExpr(cmd) and
|
QuotedCommandInCreateProcessFunction::hasFlowToExpr(cmd) and
|
||||||
msg2 =
|
msg2 =
|
||||||
" and with an unquoted lpCommandLine (" + cmd +
|
" and with an unquoted lpCommandLine (" + cmd +
|
||||||
") introduces a security vulnerability if the path contains spaces."
|
") introduces a security vulnerability if the path contains spaces."
|
||||||
|
|||||||
Reference in New Issue
Block a user