Skip to content

Commit 6b6c317

Browse files
committed
Allow MaD barriers
This commit was done by Opus 4.5 with the following prompt: In the commit 004d40e I have made it so that C# CodeQL queries which use sinks defined using data extensions (also known as "models-as-data"), which are accessed using `sinkNode(Node node, string kind)`, also use barriers defined using models-as-data, which are accessed using `barrierNode(Node node, string kind)`, with the same `kind` string. Please do the same for C++. If there are any complicated cases then list them at the end for me to do manually.
1 parent 8257475 commit 6b6c317

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,27 @@ predicate summaryModel(
249249
)
250250
}
251251

252+
/**
253+
* Holds if a barrier model exists for the given parameters.
254+
*/
255+
predicate barrierModel(
256+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
257+
string output, string kind, string provenance, string model
258+
) {
259+
MaD::barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model)
260+
}
261+
262+
/**
263+
* Holds if a barrier guard model exists for the given parameters.
264+
*/
265+
predicate barrierGuardModel(
266+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
267+
string input, string acceptingvalue, string kind, string provenance, string model
268+
) {
269+
MaD::barrierGuardModel(namespace, type, subtypes, name, signature, ext, input, acceptingvalue,
270+
kind, provenance, model)
271+
}
272+
252273
/** Provides a query predicate to check the CSV data for validation errors. */
253274
module CsvValidation {
254275
private string getInvalidModelInput() {
@@ -1028,6 +1049,17 @@ private module Cached {
10281049
isSinkNode(n, kind, model) and n.asNode() = node
10291050
)
10301051
}
1052+
1053+
/**
1054+
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
1055+
* model.
1056+
*/
1057+
cached
1058+
predicate barrierNode(DataFlow::Node node, string kind, string model) {
1059+
exists(SourceSinkInterpretationInput::InterpretNode n |
1060+
isBarrierNode(n, kind, model) and n.asNode() = node
1061+
)
1062+
}
10311063
}
10321064

10331065
import Cached
@@ -1044,6 +1076,12 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind,
10441076
*/
10451077
predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) }
10461078

1079+
/**
1080+
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
1081+
* model.
1082+
*/
1083+
predicate barrierNode(DataFlow::Node node, string kind) { barrierNode(node, kind, _) }
1084+
10471085
private predicate interpretSummary(
10481086
Function f, string input, string output, string kind, string provenance, string model
10491087
) {

cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,16 +149,27 @@ module SourceSinkInterpretationInput implements
149149
}
150150

151151
predicate barrierElement(
152-
Element n, string output, string kind, Public::Provenance provenance, string model
152+
Element e, string output, string kind, Public::Provenance provenance, string model
153153
) {
154-
none()
154+
exists(
155+
string namespace, string type, boolean subtypes, string name, string signature, string ext
156+
|
157+
barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
158+
e = interpretElement(namespace, type, subtypes, name, signature, ext)
159+
)
155160
}
156161

157162
predicate barrierGuardElement(
158-
Element n, string input, Public::AcceptingValue acceptingvalue, string kind,
163+
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
159164
Public::Provenance provenance, string model
160165
) {
161-
none()
166+
exists(
167+
string namespace, string type, boolean subtypes, string name, string signature, string ext
168+
|
169+
barrierGuardModel(namespace, type, subtypes, name, signature, ext, input, acceptingvalue,
170+
kind, provenance, model) and
171+
e = interpretElement(namespace, type, subtypes, name, signature, ext)
172+
)
162173
}
163174

164175
private newtype TInterpretNode =

cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ module SqlTaintedConfig implements DataFlow::ConfigSig {
4545

4646
predicate isBarrier(DataFlow::Node node) {
4747
node.asExpr().getUnspecifiedType() instanceof IntegralType
48+
or
49+
// barrier defined using models-as-data
50+
barrierNode(node, "sql-injection")
4851
}
4952

5053
predicate isBarrierIn(DataFlow::Node node) {

0 commit comments

Comments
 (0)