diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 7232326f1b3d..efa5736b6d37 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -249,6 +249,27 @@ predicate summaryModel( ) } +/** + * Holds if a barrier model exists for the given parameters. + */ +predicate barrierModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance, string model +) { + MaD::barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) +} + +/** + * Holds if a barrier guard model exists for the given parameters. + */ +predicate barrierGuardModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string input, string acceptingvalue, string kind, string provenance, string model +) { + MaD::barrierGuardModel(namespace, type, subtypes, name, signature, ext, input, acceptingvalue, + kind, provenance, model) +} + /** Provides a query predicate to check the CSV data for validation errors. */ module CsvValidation { private string getInvalidModelInput() { @@ -1028,6 +1049,17 @@ private module Cached { isSinkNode(n, kind, model) and n.asNode() = node ) } + + /** + * Holds if `node` is specified as a barrier with the given kind in a MaD flow + * model. + */ + cached + predicate barrierNode(DataFlow::Node node, string kind, string model) { + exists(SourceSinkInterpretationInput::InterpretNode n | + isBarrierNode(n, kind, model) and n.asNode() = node + ) + } } import Cached @@ -1044,6 +1076,12 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind, */ predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) } +/** + * Holds if `node` is specified as a barrier with the given kind in a MaD flow + * model. + */ +predicate barrierNode(DataFlow::Node node, string kind) { barrierNode(node, kind, _) } + private predicate interpretSummary( Function f, string input, string output, string kind, string provenance, string model ) { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll index a1d9dd86c400..53b26aad9309 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll @@ -149,16 +149,27 @@ module SourceSinkInterpretationInput implements } predicate barrierElement( - Element n, string output, string kind, Public::Provenance provenance, string model + Element e, string output, string kind, Public::Provenance provenance, string model ) { - none() + exists( + string namespace, string type, boolean subtypes, string name, string signature, string ext + | + barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and + e = interpretElement(namespace, type, subtypes, name, signature, ext) + ) } predicate barrierGuardElement( - Element n, string input, Public::AcceptingValue acceptingvalue, string kind, + Element e, string input, Public::AcceptingValue acceptingvalue, string kind, Public::Provenance provenance, string model ) { - none() + exists( + string namespace, string type, boolean subtypes, string name, string signature, string ext + | + barrierGuardModel(namespace, type, subtypes, name, signature, ext, input, acceptingvalue, + kind, provenance, model) and + e = interpretElement(namespace, type, subtypes, name, signature, ext) + ) } private newtype TInterpretNode = diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql index 5d08afbe304a..8b04b986b891 100644 --- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -45,6 +45,9 @@ module SqlTaintedConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node.asExpr().getUnspecifiedType() instanceof IntegralType + or + // barrier defined using models-as-data + barrierNode(node, "sql-injection") } predicate isBarrierIn(DataFlow::Node node) {