mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
C++: SqlPqxxTainted.ql style fixes
This commit is contained in:
@@ -13,9 +13,6 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
// import semmle.code.cpp.security.FunctionWithWrappers
|
||||
// import semmle.code.cpp.security.TaintTracking
|
||||
// import TaintedWithPath
|
||||
import semmle.code.cpp.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
@@ -69,102 +66,74 @@ predicate pqxxTransactionSqlArgument(string function, int arg) {
|
||||
function = "stream" and arg = 0
|
||||
}
|
||||
|
||||
predicate pqxxConnectionSqlArgument(string function, int arg) {
|
||||
function = "prepare" and arg = 1
|
||||
}
|
||||
predicate pqxxConnectionSqlArgument(string function, int arg) { function = "prepare" and arg = 1 }
|
||||
|
||||
Expr getPqxxSqlArgument() {
|
||||
exists(FunctionCall fc, Expr e, int argIndex, Type t |
|
||||
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
|
||||
e = fc.getQualifier() and
|
||||
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
|
||||
// and return pointer to a connection/transation object
|
||||
e.getType().refersTo(t) and
|
||||
// transation exec and connection prepare variations
|
||||
(
|
||||
pqxxTransationClassNames(t.getName(), _) and pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex)
|
||||
or
|
||||
pqxxConnectionClassNames(t.getName(), _) and pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex)
|
||||
)
|
||||
and
|
||||
result = fc.getArgument(argIndex)
|
||||
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
|
||||
e = fc.getQualifier() and
|
||||
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
|
||||
// and return pointer to a connection/transation object
|
||||
e.getType().refersTo(t) and
|
||||
// transation exec and connection prepare variations
|
||||
(
|
||||
pqxxTransationClassNames(t.getName(), _) and
|
||||
pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex)
|
||||
or
|
||||
pqxxConnectionClassNames(t.getName(), _) and
|
||||
pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex)
|
||||
) and
|
||||
result = fc.getArgument(argIndex)
|
||||
)
|
||||
}
|
||||
|
||||
predicate pqxxEscapeArgument(string function, int arg) {
|
||||
arg = 0 and
|
||||
(
|
||||
function = "esc"
|
||||
or
|
||||
function = "esc_raw"
|
||||
or
|
||||
function = "quote"
|
||||
or
|
||||
function = "quote_raw"
|
||||
or
|
||||
function = "quote_name"
|
||||
or
|
||||
function = "quote_table"
|
||||
or
|
||||
function = "esc_like"
|
||||
function = "esc"
|
||||
or
|
||||
function = "esc_raw"
|
||||
or
|
||||
function = "quote"
|
||||
or
|
||||
function = "quote_raw"
|
||||
or
|
||||
function = "quote_name"
|
||||
or
|
||||
function = "quote_table"
|
||||
or
|
||||
function = "esc_like"
|
||||
)
|
||||
}
|
||||
|
||||
predicate isEscapedPqxxArgument(Expr argExpr) {
|
||||
exists(FunctionCall fc, Expr e, int argIndex, Type t |
|
||||
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
|
||||
e = fc.getQualifier() and
|
||||
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
|
||||
// and return pointer to a connection/transation object
|
||||
e.getType().refersTo(t) and
|
||||
// transation and connection escape functions
|
||||
(pqxxTransationClassNames(t.getName(), _) or pqxxConnectionClassNames(t.getName(), _))
|
||||
and
|
||||
pqxxEscapeArgument(fc.getTarget().getName(), argIndex)
|
||||
and
|
||||
// eval is escaped
|
||||
argExpr = fc.getArgument(argIndex)
|
||||
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
|
||||
e = fc.getQualifier() and
|
||||
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
|
||||
// and return pointer to a connection/transation object
|
||||
e.getType().refersTo(t) and
|
||||
// transation and connection escape functions
|
||||
(pqxxTransationClassNames(t.getName(), _) or pqxxConnectionClassNames(t.getName(), _)) and
|
||||
pqxxEscapeArgument(fc.getTarget().getName(), argIndex) and
|
||||
// eval is escaped
|
||||
argExpr = fc.getArgument(argIndex)
|
||||
)
|
||||
}
|
||||
|
||||
// class Configuration extends TaintTrackingConfiguration {
|
||||
// override predicate isSink(Element tainted) {
|
||||
// tainted = getPqxxSqlArgument()
|
||||
// }
|
||||
// override predicate isBarrier(Expr e) {
|
||||
// super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
|
||||
// }
|
||||
// }
|
||||
// from
|
||||
// Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode, string taintCause
|
||||
// where
|
||||
// taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||
// isUserInput(taintSource, taintCause)
|
||||
// select taintedArg, sourceNode, sinkNode,
|
||||
// "This argument to a SQL query function is derived from $@", taintSource, "user input (" + taintCause + ")"
|
||||
|
||||
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "SqlPqxxTainted" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
isUserInput(source.asExpr(), _)
|
||||
}
|
||||
override predicate isSource(DataFlow::Node source) { isUserInput(source.asExpr(), _) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink.asExpr() = getPqxxSqlArgument()
|
||||
}
|
||||
override predicate isSink(DataFlow::Node sink) { sink.asExpr() = getPqxxSqlArgument() }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
isEscapedPqxxArgument(node.asExpr())
|
||||
}
|
||||
override predicate isSanitizer(DataFlow::Node node) { isEscapedPqxxArgument(node.asExpr()) }
|
||||
}
|
||||
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause
|
||||
where
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause
|
||||
where
|
||||
config.hasFlowPath(source, sink) and
|
||||
isUserInput(source.getNode().asExpr(), taintCause)
|
||||
select
|
||||
sink, source, sink,
|
||||
"This argument to a SQL query function is derived from $@", source, "user input (" + taintCause + ")"
|
||||
select sink, source, sink, "This argument to a SQL query function is derived from $@", source,
|
||||
"user input (" + taintCause + ")"
|
||||
|
||||
Reference in New Issue
Block a user