mirror of
https://github.com/github/codeql.git
synced 2026-07-06 20:15:37 +02:00
Compare commits
4 Commits
bazookamus
...
temp-dca-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66743b4351 | ||
|
|
c31c5cacde | ||
|
|
c84c6f33a9 | ||
|
|
5aa0429e97 |
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
category: breaking
|
|
||||||
---
|
|
||||||
* Removed support for using variables as sources and sinks in models-as-data. Users of this feature should convert such sources and sinks to models defined using the QL language.
|
|
||||||
@@ -931,6 +931,31 @@ private Element interpretElement0(
|
|||||||
signature = "" and
|
signature = "" and
|
||||||
elementSpec(namespace, type, subtypes, name, signature, _)
|
elementSpec(namespace, type, subtypes, name, signature, _)
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
// Member variables
|
||||||
|
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||||
|
signature = "" and
|
||||||
|
exists(Class namedClass, Class classWithMember, MemberVariable member |
|
||||||
|
member.getName() = name and
|
||||||
|
member = classWithMember.getAMember() and
|
||||||
|
namedClass.hasQualifiedName(namespace, type) and
|
||||||
|
result = member
|
||||||
|
|
|
||||||
|
// field declared in the named type or a subtype of it (or an extension of any)
|
||||||
|
subtypes = true and
|
||||||
|
classWithMember = namedClass.getADerivedClass*()
|
||||||
|
or
|
||||||
|
// field declared directly in the named type (or an extension of it)
|
||||||
|
subtypes = false and
|
||||||
|
classWithMember = namedClass
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// Global or namespace variables
|
||||||
|
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||||
|
signature = "" and
|
||||||
|
type = "" and
|
||||||
|
subtypes = false and
|
||||||
|
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ private import cpp as Cpp
|
|||||||
private import codeql.dataflow.internal.FlowSummaryImpl
|
private import codeql.dataflow.internal.FlowSummaryImpl
|
||||||
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
|
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
|
||||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
|
|
||||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific
|
||||||
private import semmle.code.cpp.dataflow.ExternalFlow
|
private import semmle.code.cpp.dataflow.ExternalFlow
|
||||||
@@ -21,22 +20,8 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
|
|||||||
|
|
||||||
class SinkBase = Void;
|
class SinkBase = Void;
|
||||||
|
|
||||||
class FlowSummaryCallBase = CallInstruction;
|
|
||||||
|
|
||||||
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
|
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
|
||||||
|
|
||||||
FlowSummaryCallBase getASourceCall(SummarizedCallableBase sc) {
|
|
||||||
result.getStaticCallTarget() = sc
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCallable getSummarizedCallableAsDataFlowCallable(SummarizedCallableBase c) {
|
|
||||||
result.asSummarizedCallable() = c
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCallable getSourceCallEnclosingCallable(FlowSummaryCallBase call) {
|
|
||||||
result.asSourceCallable() = call.getEnclosingFunction()
|
|
||||||
}
|
|
||||||
|
|
||||||
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
|
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
|
||||||
|
|
||||||
ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") }
|
ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") }
|
||||||
@@ -45,10 +30,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
|
|||||||
arg = repeatStars(result.(NormalReturnKind).getIndirectionIndex())
|
arg = repeatStars(result.(NormalReturnKind).getIndirectionIndex())
|
||||||
}
|
}
|
||||||
|
|
||||||
ParameterPosition getFlowSummaryParameterPosition(ReturnKind rk) {
|
|
||||||
result = TFlowSummaryPosition(rk)
|
|
||||||
}
|
|
||||||
|
|
||||||
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
|
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
|
||||||
|
|
||||||
string encodeArgumentPosition(ArgumentPosition pos) { result = pos.toString() }
|
string encodeArgumentPosition(ArgumentPosition pos) { result = pos.toString() }
|
||||||
@@ -133,22 +114,10 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
|
|||||||
private import Make<Location, DataFlowImplSpecific::CppDataFlow, Input> as Impl
|
private import Make<Location, DataFlowImplSpecific::CppDataFlow, Input> as Impl
|
||||||
|
|
||||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||||
Impl::Private::SummaryNode getSummaryNode(Node n) {
|
|
||||||
result = n.(FlowSummaryNode).getSummaryNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
||||||
result.getStaticCallTarget().getUnderlyingCallable() = sc
|
result.getStaticCallTarget().getUnderlyingCallable() = sc
|
||||||
}
|
}
|
||||||
|
|
||||||
Node getSourceOutNode(Input::FlowSummaryCallBase call, ReturnKind rk) {
|
|
||||||
exists(IndirectReturnOutNode out | result = out |
|
|
||||||
out.getCallInstruction() = call and
|
|
||||||
pragma[only_bind_out](rk.(NormalReturnKind).getIndirectionIndex()) =
|
|
||||||
pragma[only_bind_out](out.getIndirectionIndex())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() }
|
DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() }
|
||||||
|
|
||||||
Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() }
|
Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() }
|
||||||
@@ -261,11 +230,40 @@ module SourceSinkInterpretationInput implements
|
|||||||
|
|
||||||
/** Provides additional sink specification logic. */
|
/** Provides additional sink specification logic. */
|
||||||
bindingset[c]
|
bindingset[c]
|
||||||
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) { none() }
|
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
|
||||||
|
// Allow variables to be picked as output nodes.
|
||||||
|
exists(Node n, Element ast |
|
||||||
|
n = node.asNode() and
|
||||||
|
ast = mid.asElement()
|
||||||
|
|
|
||||||
|
c = "" and
|
||||||
|
n.asExpr().(VariableAccess).getTarget() = ast
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/** Provides additional source specification logic. */
|
/** Provides additional source specification logic. */
|
||||||
bindingset[c]
|
bindingset[c]
|
||||||
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) { none() }
|
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
|
||||||
|
exists(Node n, Element ast, VariableAccess e |
|
||||||
|
n = node.asNode() and
|
||||||
|
ast = mid.asElement() and
|
||||||
|
e.getTarget() = ast
|
||||||
|
|
|
||||||
|
// Allow variables to be picked as input nodes.
|
||||||
|
// We could simply do this as `e = n.asExpr()`, but that would not allow
|
||||||
|
// us to pick `x` as a sink in an example such as `x = source()` (but
|
||||||
|
// only subsequent uses of `x`) since the variable access on `x` doesn't
|
||||||
|
// actually load the value of `x`. So instead, we pick the instruction
|
||||||
|
// node corresponding to the generated `StoreInstruction` and use the
|
||||||
|
// expression associated with the destination instruction. This means
|
||||||
|
// that the `x` in `x = source()` can be marked as an input.
|
||||||
|
c = "" and
|
||||||
|
exists(StoreInstruction store |
|
||||||
|
store.getDestinationAddress().getUnconvertedResultExpression() = e and
|
||||||
|
n.asInstruction() = store
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module Private {
|
module Private {
|
||||||
|
|||||||
@@ -1534,8 +1534,12 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
|
|||||||
result = this.getSummaryNode().getSummarizedCallable()
|
result = this.getSummaryNode().getSummarizedCallable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the enclosing callable. For a `FlowSummaryNode` this is always the
|
||||||
|
* summarized function this node is part of.
|
||||||
|
*/
|
||||||
override DataFlowCallable getEnclosingCallable() {
|
override DataFlowCallable getEnclosingCallable() {
|
||||||
result = FlowSummaryImpl::Private::getEnclosingCallable(this.getSummaryNode())
|
result.asSummarizedCallable() = this.getSummarizedCallable()
|
||||||
}
|
}
|
||||||
|
|
||||||
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
|
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
|
||||||
|
|||||||
@@ -561,21 +561,6 @@ class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An argument node that re-enters return output as input to a flow summary. */
|
|
||||||
private class FlowSummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
|
|
||||||
private CallInstruction callInstruction;
|
|
||||||
private ReturnKind rk;
|
|
||||||
|
|
||||||
FlowSummaryArgumentNode() {
|
|
||||||
this.getSummaryNode() = FlowSummaryImpl::Private::summaryArgumentNode(callInstruction, rk)
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
|
||||||
call.asCallInstruction() = callInstruction and
|
|
||||||
pos = TFlowSummaryPosition(rk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A parameter position represented by an integer. */
|
/** A parameter position represented by an integer. */
|
||||||
class ParameterPosition = Position;
|
class ParameterPosition = Position;
|
||||||
|
|
||||||
@@ -631,18 +616,6 @@ class IndirectionPosition extends Position, TIndirectionPosition {
|
|||||||
final override int getIndirectionIndex() { result = indirectionIndex }
|
final override int getIndirectionIndex() { result = indirectionIndex }
|
||||||
}
|
}
|
||||||
|
|
||||||
class FlowSummaryPosition extends Position, TFlowSummaryPosition {
|
|
||||||
ReturnKind rk;
|
|
||||||
|
|
||||||
FlowSummaryPosition() { this = TFlowSummaryPosition(rk) }
|
|
||||||
|
|
||||||
override string toString() { result = "write to: " + rk.toString() }
|
|
||||||
|
|
||||||
override int getArgumentIndex() { none() }
|
|
||||||
|
|
||||||
final override int getIndirectionIndex() { result = rk.getIndirectionIndex() }
|
|
||||||
}
|
|
||||||
|
|
||||||
newtype TPosition =
|
newtype TPosition =
|
||||||
TDirectPosition(int argumentIndex) {
|
TDirectPosition(int argumentIndex) {
|
||||||
exists(any(CallInstruction c).getArgument(argumentIndex))
|
exists(any(CallInstruction c).getArgument(argumentIndex))
|
||||||
@@ -661,8 +634,7 @@ newtype TPosition =
|
|||||||
p = f.getParameter(argumentIndex) and
|
p = f.getParameter(argumentIndex) and
|
||||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
|
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
|
||||||
)
|
)
|
||||||
} or
|
}
|
||||||
TFlowSummaryPosition(ReturnKind rk) { FlowSummaryImpl::Private::relevantFlowSummaryPosition(rk) }
|
|
||||||
|
|
||||||
private newtype TReturnKind =
|
private newtype TReturnKind =
|
||||||
TNormalReturnKind(int indirectionIndex) {
|
TNormalReturnKind(int indirectionIndex) {
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ private module Cached {
|
|||||||
model = ""
|
model = ""
|
||||||
or
|
or
|
||||||
// models-as-data summarized flow
|
// models-as-data summarized flow
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ private module Cached {
|
|||||||
model = ""
|
model = ""
|
||||||
or
|
or
|
||||||
// models-as-data summarized flow
|
// models-as-data summarized flow
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
||||||
or
|
or
|
||||||
// object->field conflation for content that is a `TaintInheritingContent`.
|
// object->field conflation for content that is a `TaintInheritingContent`.
|
||||||
|
|||||||
@@ -53,17 +53,14 @@ models
|
|||||||
| 52 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
| 52 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||||
| 53 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 53 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
| 54 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 54 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
| 55 | Summary: ; MyString; true; operator[]; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
| 55 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
|
||||||
| 56 | Summary: ; MyString; true; operator[]; ; ; ReturnValue[*]; Argument[-1]; taint; manual |
|
| 56 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
|
||||||
| 57 | Summary: ; ReverseFlow; true; get_ptr; ; ; ReturnValue[*]; Argument[-1].Field[ReverseFlow::value]; value; manual |
|
| 57 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
|
||||||
| 58 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
|
| 58 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||||
| 59 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
|
| 59 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||||
| 60 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
|
| 60 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||||
| 61 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
| 61 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||||
| 62 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
| 62 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||||
| 63 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
|
||||||
| 64 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
|
||||||
| 65 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
|
||||||
edges
|
edges
|
||||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
|
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
|
||||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
|
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
|
||||||
@@ -72,16 +69,16 @@ edges
|
|||||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
|
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
|
||||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:65 |
|
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:62 |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:61 |
|
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:58 |
|
||||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:62 |
|
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:59 |
|
||||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:63 |
|
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:60 |
|
||||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||||
@@ -97,10 +94,10 @@ edges
|
|||||||
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
|
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
|
||||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
|
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
|
||||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:63 |
|
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:60 |
|
||||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:64 |
|
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:61 |
|
||||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
|
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
|
||||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||||
@@ -162,27 +159,27 @@ edges
|
|||||||
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
|
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
|
||||||
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
|
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
|
||||||
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
|
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
|
||||||
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:59 |
|
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:56 |
|
||||||
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 |
|
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
|
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
|
||||||
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
|
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
|
||||||
| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
|
| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
|
||||||
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:60 |
|
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:57 |
|
||||||
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 |
|
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
|
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
|
||||||
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
|
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
|
||||||
| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
|
| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
|
||||||
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:60 |
|
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:57 |
|
||||||
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
|
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
|
||||||
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
|
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
|
||||||
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
|
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
|
||||||
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:58 |
|
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:55 |
|
||||||
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 |
|
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
|
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
|
||||||
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
|
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
|
||||||
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
|
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
|
||||||
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
|
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
|
||||||
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:58 |
|
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:55 |
|
||||||
| test.cpp:186:2:186:2 | *s [post update] [myField] | test.cpp:187:33:187:34 | *& ... [myField] | provenance | |
|
| test.cpp:186:2:186:2 | *s [post update] [myField] | test.cpp:187:33:187:34 | *& ... [myField] | provenance | |
|
||||||
| test.cpp:186:2:186:24 | ... = ... | test.cpp:186:2:186:2 | *s [post update] [myField] | provenance | |
|
| test.cpp:186:2:186:24 | ... = ... | test.cpp:186:2:186:2 | *s [post update] [myField] | provenance | |
|
||||||
| test.cpp:186:14:186:22 | call to ymlSource | test.cpp:186:2:186:24 | ... = ... | provenance | Src:MaD:25 |
|
| test.cpp:186:14:186:22 | call to ymlSource | test.cpp:186:2:186:24 | ... = ... | provenance | Src:MaD:25 |
|
||||||
@@ -195,18 +192,6 @@ edges
|
|||||||
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | |
|
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | |
|
||||||
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:201:10:201:10 | x | provenance | Sink:MaD:1 |
|
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:201:10:201:10 | x | provenance | Sink:MaD:1 |
|
||||||
| test.cpp:200:35:200:36 | *& ... [myField] | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | MaD:51 |
|
| test.cpp:200:35:200:36 | *& ... [myField] | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | MaD:51 |
|
||||||
| test.cpp:216:3:216:4 | get_ptr output argument [value] | test.cpp:217:11:217:12 | *rf [value] | provenance | |
|
|
||||||
| test.cpp:216:3:216:28 | ... = ... | test.cpp:216:3:216:4 | get_ptr output argument [value] | provenance | MaD:57 |
|
|
||||||
| test.cpp:216:18:216:26 | call to ymlSource | test.cpp:216:3:216:28 | ... = ... | provenance | Src:MaD:25 |
|
|
||||||
| test.cpp:217:11:217:12 | *rf [value] | test.cpp:217:14:217:18 | value | provenance | |
|
|
||||||
| test.cpp:217:14:217:18 | value | test.cpp:217:14:217:18 | value | provenance | |
|
|
||||||
| test.cpp:217:14:217:18 | value | test.cpp:218:11:218:11 | x | provenance | Sink:MaD:1 |
|
|
||||||
| test.cpp:222:3:222:3 | operator[] output argument | test.cpp:223:12:223:12 | *s | provenance | |
|
|
||||||
| test.cpp:222:3:222:20 | ... = ... | test.cpp:222:3:222:3 | operator[] output argument | provenance | MaD:56 |
|
|
||||||
| test.cpp:222:10:222:20 | call to ymlSource | test.cpp:222:3:222:20 | ... = ... | provenance | Src:MaD:25 |
|
|
||||||
| test.cpp:223:12:223:12 | *s | test.cpp:223:13:223:15 | call to operator[] | provenance | MaD:55 |
|
|
||||||
| test.cpp:223:13:223:15 | call to operator[] | test.cpp:223:13:223:15 | call to operator[] | provenance | |
|
|
||||||
| test.cpp:223:13:223:15 | call to operator[] | test.cpp:224:11:224:11 | c | provenance | Sink:MaD:1 |
|
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
|
||||||
@@ -485,20 +470,6 @@ nodes
|
|||||||
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | semmle.label | call to read_field_from_struct_2 |
|
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | semmle.label | call to read_field_from_struct_2 |
|
||||||
| test.cpp:200:35:200:36 | *& ... [myField] | semmle.label | *& ... [myField] |
|
| test.cpp:200:35:200:36 | *& ... [myField] | semmle.label | *& ... [myField] |
|
||||||
| test.cpp:201:10:201:10 | x | semmle.label | x |
|
| test.cpp:201:10:201:10 | x | semmle.label | x |
|
||||||
| test.cpp:216:3:216:4 | get_ptr output argument [value] | semmle.label | get_ptr output argument [value] |
|
|
||||||
| test.cpp:216:3:216:28 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:216:18:216:26 | call to ymlSource | semmle.label | call to ymlSource |
|
|
||||||
| test.cpp:217:11:217:12 | *rf [value] | semmle.label | *rf [value] |
|
|
||||||
| test.cpp:217:14:217:18 | value | semmle.label | value |
|
|
||||||
| test.cpp:217:14:217:18 | value | semmle.label | value |
|
|
||||||
| test.cpp:218:11:218:11 | x | semmle.label | x |
|
|
||||||
| test.cpp:222:3:222:3 | operator[] output argument | semmle.label | operator[] output argument |
|
|
||||||
| test.cpp:222:3:222:20 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:222:10:222:20 | call to ymlSource | semmle.label | call to ymlSource |
|
|
||||||
| test.cpp:223:12:223:12 | *s | semmle.label | *s |
|
|
||||||
| test.cpp:223:13:223:15 | call to operator[] | semmle.label | call to operator[] |
|
|
||||||
| test.cpp:223:13:223:15 | call to operator[] | semmle.label | call to operator[] |
|
|
||||||
| test.cpp:224:11:224:11 | c | semmle.label | c |
|
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
||||||
| windows.cpp:24:8:24:11 | * ... | semmle.label | * ... |
|
| windows.cpp:24:8:24:11 | * ... | semmle.label | * ... |
|
||||||
|
|||||||
@@ -24,6 +24,3 @@ extensions:
|
|||||||
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||||
- ["", "", False, "read_field_from_struct", "", "", "Argument[*0].Field[MyNamespace::MyStructInNamespace::myField]", "ReturnValue", "value", "manual"]
|
- ["", "", False, "read_field_from_struct", "", "", "Argument[*0].Field[MyNamespace::MyStructInNamespace::myField]", "ReturnValue", "value", "manual"]
|
||||||
- ["", "", False, "read_field_from_struct_2", "", "", "Argument[*0].Field[MyGlobalStruct::myField]", "ReturnValue", "value", "manual"]
|
- ["", "", False, "read_field_from_struct_2", "", "", "Argument[*0].Field[MyGlobalStruct::myField]", "ReturnValue", "value", "manual"]
|
||||||
- ["", "ReverseFlow", True, "get_ptr", "", "", "ReturnValue[*]", "Argument[-1].Field[ReverseFlow::value]", "value", "manual"]
|
|
||||||
- ["", "MyString", True, "operator[]", "", "", "ReturnValue[*]", "Argument[-1]", "taint", "manual"]
|
|
||||||
- ["", "MyString", True, "operator[]", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
|
||||||
|
|||||||
@@ -21,5 +21,3 @@
|
|||||||
| test.cpp:173:10:173:10 | y | test-sink |
|
| test.cpp:173:10:173:10 | y | test-sink |
|
||||||
| test.cpp:188:10:188:10 | x | test-sink |
|
| test.cpp:188:10:188:10 | x | test-sink |
|
||||||
| test.cpp:201:10:201:10 | x | test-sink |
|
| test.cpp:201:10:201:10 | x | test-sink |
|
||||||
| test.cpp:218:11:218:11 | x | test-sink |
|
|
||||||
| test.cpp:224:11:224:11 | c | test-sink |
|
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
| test.cpp:170:10:170:18 | call to ymlSource | local |
|
| test.cpp:170:10:170:18 | call to ymlSource | local |
|
||||||
| test.cpp:186:14:186:22 | call to ymlSource | local |
|
| test.cpp:186:14:186:22 | call to ymlSource | local |
|
||||||
| test.cpp:199:14:199:22 | call to ymlSource | local |
|
| test.cpp:199:14:199:22 | call to ymlSource | local |
|
||||||
| test.cpp:216:18:216:26 | call to ymlSource | local |
|
|
||||||
| test.cpp:222:10:222:20 | call to ymlSource | local |
|
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
||||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
||||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
||||||
|
|||||||
@@ -200,27 +200,3 @@ void test_fully_qualified_field_test_2() {
|
|||||||
int x = read_field_from_struct_2(&s);
|
int x = read_field_from_struct_2(&s);
|
||||||
ymlSink(x); // $ ir
|
ymlSink(x); // $ ir
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ReverseFlow {
|
|
||||||
int value;
|
|
||||||
int& get_ptr();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MyString {
|
|
||||||
char& operator[](unsigned);
|
|
||||||
};
|
|
||||||
|
|
||||||
void test_reverse_flow(unsigned i, unsigned j) {
|
|
||||||
{
|
|
||||||
ReverseFlow rf;
|
|
||||||
rf.get_ptr() = ymlSource();
|
|
||||||
int x = rf.value;
|
|
||||||
ymlSink(x); // $ ir
|
|
||||||
}
|
|
||||||
{
|
|
||||||
MyString s;
|
|
||||||
s[i] = ymlSource();
|
|
||||||
char c = s[j];
|
|
||||||
ymlSink(c); // $ ir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,34 +33,34 @@ summaryCalls
|
|||||||
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturnFirst in madCallArg0ReturnToReturnFirst |
|
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturnFirst in madCallArg0ReturnToReturnFirst |
|
||||||
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0WithValue in madCallArg0WithValue |
|
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0WithValue in madCallArg0WithValue |
|
||||||
summarizedCallables
|
summarizedCallables
|
||||||
| tests.cpp:127:5:127:19 | madArg0ToReturn |
|
| tests.cpp:144:5:144:19 | madArg0ToReturn |
|
||||||
| tests.cpp:128:6:128:28 | madArg0ToReturnIndirect |
|
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
|
||||||
| tests.cpp:130:5:130:28 | madArg0ToReturnValueFlow |
|
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
|
||||||
| tests.cpp:131:5:131:27 | madArg0IndirectToReturn |
|
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
|
||||||
| tests.cpp:132:5:132:33 | madArg0DoubleIndirectToReturn |
|
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
|
||||||
| tests.cpp:133:5:133:30 | madArg0NotIndirectToReturn |
|
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
|
||||||
| tests.cpp:134:6:134:26 | madArg0ToArg1Indirect |
|
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
|
||||||
| tests.cpp:135:6:135:34 | madArg0IndirectToArg1Indirect |
|
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
|
||||||
| tests.cpp:136:5:136:18 | madArgsComplex |
|
| tests.cpp:153:5:153:18 | madArgsComplex |
|
||||||
| tests.cpp:137:5:137:14 | madArgsAny |
|
| tests.cpp:154:5:154:14 | madArgsAny |
|
||||||
| tests.cpp:138:5:138:28 | madAndImplementedComplex |
|
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
|
||||||
| tests.cpp:143:5:143:24 | madArg0FieldToReturn |
|
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
|
||||||
| tests.cpp:144:5:144:32 | madArg0IndirectFieldToReturn |
|
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
|
||||||
| tests.cpp:145:5:145:32 | madArg0FieldIndirectToReturn |
|
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
|
||||||
| tests.cpp:146:13:146:32 | madArg0ToReturnField |
|
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
|
||||||
| tests.cpp:147:14:147:41 | madArg0ToReturnIndirectField |
|
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
|
||||||
| tests.cpp:148:13:148:40 | madArg0ToReturnFieldIndirect |
|
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
|
||||||
| tests.cpp:250:7:250:19 | madArg0ToSelf |
|
| tests.cpp:284:7:284:19 | madArg0ToSelf |
|
||||||
| tests.cpp:251:6:251:20 | madSelfToReturn |
|
| tests.cpp:285:6:285:20 | madSelfToReturn |
|
||||||
| tests.cpp:253:7:253:20 | madArg0ToField |
|
| tests.cpp:287:7:287:20 | madArg0ToField |
|
||||||
| tests.cpp:254:6:254:21 | madFieldToReturn |
|
| tests.cpp:288:6:288:21 | madFieldToReturn |
|
||||||
| tests.cpp:277:7:277:30 | namespaceMadSelfToReturn |
|
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
|
||||||
| tests.cpp:392:5:392:29 | madCallArg0ReturnToReturn |
|
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:393:9:393:38 | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:394:6:394:25 | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
|
||||||
| tests.cpp:395:5:395:36 | madCallReturnValueIgnoreFunction |
|
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
|
||||||
| tests.cpp:417:5:417:31 | parameter_ref_to_return_ref |
|
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
|
||||||
| tests.cpp:429:5:429:17 | receive_array |
|
| tests.cpp:471:5:471:17 | receive_array |
|
||||||
sourceCallables
|
sourceCallables
|
||||||
| tests.cpp:3:5:3:10 | source |
|
| tests.cpp:3:5:3:10 | source |
|
||||||
| tests.cpp:4:6:4:14 | sourcePtr |
|
| tests.cpp:4:6:4:14 | sourcePtr |
|
||||||
@@ -82,284 +82,297 @@ sourceCallables
|
|||||||
| tests.cpp:19:6:19:32 | remoteMadSourceIndirectArg1 |
|
| tests.cpp:19:6:19:32 | remoteMadSourceIndirectArg1 |
|
||||||
| tests.cpp:19:39:19:39 | x |
|
| tests.cpp:19:39:19:39 | x |
|
||||||
| tests.cpp:19:47:19:47 | y |
|
| tests.cpp:19:47:19:47 | y |
|
||||||
| tests.cpp:23:7:23:30 | namespace2LocalMadSource |
|
| tests.cpp:20:5:20:22 | remoteMadSourceVar |
|
||||||
| tests.cpp:26:6:26:19 | localMadSource |
|
| tests.cpp:21:6:21:31 | remoteMadSourceVarIndirect |
|
||||||
| tests.cpp:28:5:28:27 | namespaceLocalMadSource |
|
| tests.cpp:24:6:24:28 | namespaceLocalMadSource |
|
||||||
| tests.cpp:30:6:30:17 | test_sources |
|
| tests.cpp:25:6:25:31 | namespaceLocalMadSourceVar |
|
||||||
| tests.cpp:45:6:45:6 | v |
|
| tests.cpp:28:7:28:30 | namespace2LocalMadSource |
|
||||||
| tests.cpp:46:7:46:16 | v_indirect |
|
| tests.cpp:31:6:31:19 | localMadSource |
|
||||||
| tests.cpp:47:6:47:13 | v_direct |
|
| tests.cpp:33:5:33:27 | namespaceLocalMadSource |
|
||||||
| tests.cpp:58:6:58:6 | a |
|
| tests.cpp:35:6:35:17 | test_sources |
|
||||||
| tests.cpp:58:9:58:9 | b |
|
| tests.cpp:50:6:50:6 | v |
|
||||||
| tests.cpp:58:12:58:12 | c |
|
| tests.cpp:51:7:51:16 | v_indirect |
|
||||||
| tests.cpp:58:15:58:15 | d |
|
| tests.cpp:52:6:52:13 | v_direct |
|
||||||
| tests.cpp:67:6:67:6 | e |
|
| tests.cpp:63:6:63:6 | a |
|
||||||
| tests.cpp:75:6:75:26 | remoteMadSourceParam0 |
|
| tests.cpp:63:9:63:9 | b |
|
||||||
| tests.cpp:75:32:75:32 | x |
|
| tests.cpp:63:12:63:12 | c |
|
||||||
| tests.cpp:82:6:82:16 | madSinkArg0 |
|
| tests.cpp:63:15:63:15 | d |
|
||||||
| tests.cpp:82:22:82:22 | x |
|
| tests.cpp:75:6:75:6 | e |
|
||||||
| tests.cpp:83:6:83:13 | notASink |
|
| tests.cpp:85:6:85:26 | remoteMadSourceParam0 |
|
||||||
| tests.cpp:83:19:83:19 | x |
|
| tests.cpp:85:32:85:32 | x |
|
||||||
| tests.cpp:84:6:84:16 | madSinkArg1 |
|
| tests.cpp:92:6:92:16 | madSinkArg0 |
|
||||||
| tests.cpp:84:22:84:22 | x |
|
| tests.cpp:92:22:92:22 | x |
|
||||||
| tests.cpp:84:29:84:29 | y |
|
| tests.cpp:93:6:93:13 | notASink |
|
||||||
| tests.cpp:85:6:85:17 | madSinkArg01 |
|
| tests.cpp:93:19:93:19 | x |
|
||||||
| tests.cpp:85:23:85:23 | x |
|
| tests.cpp:94:6:94:16 | madSinkArg1 |
|
||||||
| tests.cpp:85:30:85:30 | y |
|
| tests.cpp:94:22:94:22 | x |
|
||||||
| tests.cpp:85:37:85:37 | z |
|
| tests.cpp:94:29:94:29 | y |
|
||||||
| tests.cpp:86:6:86:17 | madSinkArg02 |
|
| tests.cpp:95:6:95:17 | madSinkArg01 |
|
||||||
| tests.cpp:86:23:86:23 | x |
|
| tests.cpp:95:23:95:23 | x |
|
||||||
| tests.cpp:86:30:86:30 | y |
|
| tests.cpp:95:30:95:30 | y |
|
||||||
| tests.cpp:86:37:86:37 | z |
|
| tests.cpp:95:37:95:37 | z |
|
||||||
| tests.cpp:87:6:87:24 | madSinkIndirectArg0 |
|
| tests.cpp:96:6:96:17 | madSinkArg02 |
|
||||||
| tests.cpp:87:31:87:31 | x |
|
| tests.cpp:96:23:96:23 | x |
|
||||||
| tests.cpp:88:6:88:30 | madSinkDoubleIndirectArg0 |
|
| tests.cpp:96:30:96:30 | y |
|
||||||
| tests.cpp:88:38:88:38 | x |
|
| tests.cpp:96:37:96:37 | z |
|
||||||
| tests.cpp:92:6:92:15 | test_sinks |
|
| tests.cpp:97:6:97:24 | madSinkIndirectArg0 |
|
||||||
| tests.cpp:106:6:106:6 | a |
|
| tests.cpp:97:31:97:31 | x |
|
||||||
| tests.cpp:107:7:107:11 | a_ptr |
|
| tests.cpp:98:6:98:30 | madSinkDoubleIndirectArg0 |
|
||||||
| tests.cpp:115:6:115:18 | madSinkParam0 |
|
| tests.cpp:98:38:98:38 | x |
|
||||||
| tests.cpp:115:24:115:24 | x |
|
| tests.cpp:99:5:99:14 | madSinkVar |
|
||||||
| tests.cpp:121:8:121:8 | operator= |
|
| tests.cpp:100:6:100:23 | madSinkVarIndirect |
|
||||||
| tests.cpp:121:8:121:8 | operator= |
|
| tests.cpp:102:6:102:15 | test_sinks |
|
||||||
| tests.cpp:121:8:121:18 | MyContainer |
|
| tests.cpp:116:6:116:6 | a |
|
||||||
| tests.cpp:122:6:122:10 | value |
|
| tests.cpp:117:7:117:11 | a_ptr |
|
||||||
| tests.cpp:123:6:123:11 | value2 |
|
| tests.cpp:132:6:132:18 | madSinkParam0 |
|
||||||
| tests.cpp:124:7:124:9 | ptr |
|
| tests.cpp:132:24:132:24 | x |
|
||||||
| tests.cpp:127:5:127:19 | madArg0ToReturn |
|
| tests.cpp:138:8:138:8 | operator= |
|
||||||
| tests.cpp:127:25:127:25 | x |
|
| tests.cpp:138:8:138:8 | operator= |
|
||||||
| tests.cpp:128:6:128:28 | madArg0ToReturnIndirect |
|
| tests.cpp:138:8:138:18 | MyContainer |
|
||||||
| tests.cpp:128:34:128:34 | x |
|
| tests.cpp:139:6:139:10 | value |
|
||||||
| tests.cpp:129:5:129:15 | notASummary |
|
| tests.cpp:140:6:140:11 | value2 |
|
||||||
| tests.cpp:129:21:129:21 | x |
|
| tests.cpp:141:7:141:9 | ptr |
|
||||||
| tests.cpp:130:5:130:28 | madArg0ToReturnValueFlow |
|
| tests.cpp:144:5:144:19 | madArg0ToReturn |
|
||||||
| tests.cpp:130:34:130:34 | x |
|
| tests.cpp:144:25:144:25 | x |
|
||||||
| tests.cpp:131:5:131:27 | madArg0IndirectToReturn |
|
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
|
||||||
| tests.cpp:131:34:131:34 | x |
|
| tests.cpp:145:34:145:34 | x |
|
||||||
| tests.cpp:132:5:132:33 | madArg0DoubleIndirectToReturn |
|
| tests.cpp:146:5:146:15 | notASummary |
|
||||||
| tests.cpp:132:41:132:41 | x |
|
| tests.cpp:146:21:146:21 | x |
|
||||||
| tests.cpp:133:5:133:30 | madArg0NotIndirectToReturn |
|
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
|
||||||
| tests.cpp:133:37:133:37 | x |
|
| tests.cpp:147:34:147:34 | x |
|
||||||
| tests.cpp:134:6:134:26 | madArg0ToArg1Indirect |
|
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
|
||||||
| tests.cpp:134:32:134:32 | x |
|
| tests.cpp:148:34:148:34 | x |
|
||||||
| tests.cpp:134:40:134:40 | y |
|
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
|
||||||
| tests.cpp:135:6:135:34 | madArg0IndirectToArg1Indirect |
|
| tests.cpp:149:41:149:41 | x |
|
||||||
| tests.cpp:135:47:135:47 | x |
|
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
|
||||||
| tests.cpp:135:55:135:55 | y |
|
| tests.cpp:150:37:150:37 | x |
|
||||||
| tests.cpp:136:5:136:18 | madArgsComplex |
|
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
|
||||||
| tests.cpp:136:25:136:25 | a |
|
| tests.cpp:151:32:151:32 | x |
|
||||||
| tests.cpp:136:33:136:33 | b |
|
| tests.cpp:151:40:151:40 | y |
|
||||||
| tests.cpp:136:40:136:40 | c |
|
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
|
||||||
| tests.cpp:136:47:136:47 | d |
|
| tests.cpp:152:47:152:47 | x |
|
||||||
| tests.cpp:137:5:137:14 | madArgsAny |
|
| tests.cpp:152:55:152:55 | y |
|
||||||
| tests.cpp:137:20:137:20 | a |
|
| tests.cpp:153:5:153:18 | madArgsComplex |
|
||||||
| tests.cpp:137:28:137:28 | b |
|
| tests.cpp:153:25:153:25 | a |
|
||||||
| tests.cpp:138:5:138:28 | madAndImplementedComplex |
|
| tests.cpp:153:33:153:33 | b |
|
||||||
| tests.cpp:138:34:138:34 | a |
|
| tests.cpp:153:40:153:40 | c |
|
||||||
| tests.cpp:138:41:138:41 | b |
|
| tests.cpp:153:47:153:47 | d |
|
||||||
| tests.cpp:138:48:138:48 | c |
|
| tests.cpp:154:5:154:14 | madArgsAny |
|
||||||
| tests.cpp:143:5:143:24 | madArg0FieldToReturn |
|
| tests.cpp:154:20:154:20 | a |
|
||||||
| tests.cpp:143:38:143:39 | mc |
|
| tests.cpp:154:28:154:28 | b |
|
||||||
| tests.cpp:144:5:144:32 | madArg0IndirectFieldToReturn |
|
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
|
||||||
| tests.cpp:144:47:144:48 | mc |
|
| tests.cpp:155:34:155:34 | a |
|
||||||
| tests.cpp:145:5:145:32 | madArg0FieldIndirectToReturn |
|
| tests.cpp:155:41:155:41 | b |
|
||||||
| tests.cpp:145:46:145:47 | mc |
|
| tests.cpp:155:48:155:48 | c |
|
||||||
| tests.cpp:146:13:146:32 | madArg0ToReturnField |
|
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
|
||||||
| tests.cpp:146:38:146:38 | x |
|
| tests.cpp:160:38:160:39 | mc |
|
||||||
| tests.cpp:147:14:147:41 | madArg0ToReturnIndirectField |
|
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
|
||||||
| tests.cpp:147:47:147:47 | x |
|
| tests.cpp:161:47:161:48 | mc |
|
||||||
| tests.cpp:148:13:148:40 | madArg0ToReturnFieldIndirect |
|
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
|
||||||
| tests.cpp:148:46:148:46 | x |
|
| tests.cpp:162:46:162:47 | mc |
|
||||||
| tests.cpp:150:6:150:19 | test_summaries |
|
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
|
||||||
| tests.cpp:153:6:153:6 | a |
|
| tests.cpp:163:38:163:38 | x |
|
||||||
| tests.cpp:153:9:153:9 | b |
|
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
|
||||||
| tests.cpp:153:12:153:12 | c |
|
| tests.cpp:164:47:164:47 | x |
|
||||||
| tests.cpp:153:15:153:15 | d |
|
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
|
||||||
| tests.cpp:153:18:153:18 | e |
|
| tests.cpp:165:46:165:46 | x |
|
||||||
| tests.cpp:154:7:154:11 | a_ptr |
|
| tests.cpp:167:13:167:30 | madFieldToFieldVar |
|
||||||
| tests.cpp:197:14:197:16 | mc1 |
|
| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
|
||||||
| tests.cpp:197:19:197:21 | mc2 |
|
| tests.cpp:169:14:169:39 | madIndirectFieldToFieldVar |
|
||||||
| tests.cpp:216:15:216:18 | rtn1 |
|
| tests.cpp:171:6:171:19 | test_summaries |
|
||||||
| tests.cpp:219:14:219:17 | rtn2 |
|
| tests.cpp:174:6:174:6 | a |
|
||||||
| tests.cpp:220:7:220:14 | rtn2_ptr |
|
| tests.cpp:174:9:174:9 | b |
|
||||||
| tests.cpp:233:7:233:7 | operator= |
|
| tests.cpp:174:12:174:12 | c |
|
||||||
| tests.cpp:233:7:233:7 | operator= |
|
| tests.cpp:174:15:174:15 | d |
|
||||||
| tests.cpp:233:7:233:13 | MyClass |
|
| tests.cpp:174:18:174:18 | e |
|
||||||
| tests.cpp:236:6:236:26 | memberRemoteMadSource |
|
| tests.cpp:175:7:175:11 | a_ptr |
|
||||||
| tests.cpp:237:7:237:39 | memberRemoteMadSourceIndirectArg0 |
|
| tests.cpp:218:14:218:16 | mc1 |
|
||||||
| tests.cpp:237:46:237:46 | x |
|
| tests.cpp:218:19:218:21 | mc2 |
|
||||||
| tests.cpp:239:7:239:21 | qualifierSource |
|
| tests.cpp:237:15:237:18 | rtn1 |
|
||||||
| tests.cpp:240:7:240:26 | qualifierFieldSource |
|
| tests.cpp:240:14:240:17 | rtn2 |
|
||||||
| tests.cpp:243:7:243:23 | memberMadSinkArg0 |
|
| tests.cpp:241:7:241:14 | rtn2_ptr |
|
||||||
| tests.cpp:243:29:243:29 | x |
|
| tests.cpp:267:7:267:7 | operator= |
|
||||||
| tests.cpp:245:7:245:19 | qualifierSink |
|
| tests.cpp:267:7:267:7 | operator= |
|
||||||
| tests.cpp:246:7:246:23 | qualifierArg0Sink |
|
| tests.cpp:267:7:267:13 | MyClass |
|
||||||
| tests.cpp:246:29:246:29 | x |
|
| tests.cpp:270:6:270:26 | memberRemoteMadSource |
|
||||||
| tests.cpp:247:7:247:24 | qualifierFieldSink |
|
| tests.cpp:271:7:271:39 | memberRemoteMadSourceIndirectArg0 |
|
||||||
| tests.cpp:250:7:250:19 | madArg0ToSelf |
|
| tests.cpp:271:46:271:46 | x |
|
||||||
| tests.cpp:250:25:250:25 | x |
|
| tests.cpp:272:6:272:29 | memberRemoteMadSourceVar |
|
||||||
| tests.cpp:251:6:251:20 | madSelfToReturn |
|
| tests.cpp:273:7:273:21 | qualifierSource |
|
||||||
| tests.cpp:252:6:252:16 | notASummary |
|
| tests.cpp:274:7:274:26 | qualifierFieldSource |
|
||||||
| tests.cpp:253:7:253:20 | madArg0ToField |
|
| tests.cpp:277:7:277:23 | memberMadSinkArg0 |
|
||||||
| tests.cpp:253:26:253:26 | x |
|
| tests.cpp:277:29:277:29 | x |
|
||||||
| tests.cpp:254:6:254:21 | madFieldToReturn |
|
| tests.cpp:278:6:278:21 | memberMadSinkVar |
|
||||||
| tests.cpp:256:6:256:8 | val |
|
| tests.cpp:279:7:279:19 | qualifierSink |
|
||||||
| tests.cpp:259:7:259:7 | MyDerivedClass |
|
| tests.cpp:280:7:280:23 | qualifierArg0Sink |
|
||||||
| tests.cpp:259:7:259:7 | operator= |
|
| tests.cpp:280:29:280:29 | x |
|
||||||
| tests.cpp:259:7:259:7 | operator= |
|
| tests.cpp:281:7:281:24 | qualifierFieldSink |
|
||||||
| tests.cpp:259:7:259:20 | MyDerivedClass |
|
| tests.cpp:284:7:284:19 | madArg0ToSelf |
|
||||||
| tests.cpp:261:6:261:28 | subtypeRemoteMadSource1 |
|
| tests.cpp:284:25:284:25 | x |
|
||||||
| tests.cpp:262:6:262:21 | subtypeNonSource |
|
| tests.cpp:285:6:285:20 | madSelfToReturn |
|
||||||
| tests.cpp:263:6:263:28 | subtypeRemoteMadSource2 |
|
| tests.cpp:286:6:286:16 | notASummary |
|
||||||
| tests.cpp:266:9:266:15 | source2 |
|
| tests.cpp:287:7:287:20 | madArg0ToField |
|
||||||
| tests.cpp:267:6:267:9 | sink |
|
| tests.cpp:287:26:287:26 | x |
|
||||||
| tests.cpp:267:19:267:20 | mc |
|
| tests.cpp:288:6:288:21 | madFieldToReturn |
|
||||||
| tests.cpp:270:8:270:8 | operator= |
|
| tests.cpp:290:6:290:8 | val |
|
||||||
| tests.cpp:270:8:270:8 | operator= |
|
| tests.cpp:293:7:293:7 | MyDerivedClass |
|
||||||
| tests.cpp:270:8:270:14 | MyClass |
|
| tests.cpp:293:7:293:7 | operator= |
|
||||||
| tests.cpp:273:8:273:33 | namespaceMemberMadSinkArg0 |
|
| tests.cpp:293:7:293:7 | operator= |
|
||||||
| tests.cpp:273:39:273:39 | x |
|
| tests.cpp:293:7:293:20 | MyDerivedClass |
|
||||||
| tests.cpp:274:15:274:46 | namespaceStaticMemberMadSinkArg0 |
|
| tests.cpp:295:6:295:28 | subtypeRemoteMadSource1 |
|
||||||
| tests.cpp:274:52:274:52 | x |
|
| tests.cpp:296:6:296:21 | subtypeNonSource |
|
||||||
| tests.cpp:277:7:277:30 | namespaceMadSelfToReturn |
|
| tests.cpp:297:6:297:28 | subtypeRemoteMadSource2 |
|
||||||
| tests.cpp:281:22:281:28 | source3 |
|
| tests.cpp:300:9:300:15 | source2 |
|
||||||
| tests.cpp:283:6:283:23 | test_class_members |
|
| tests.cpp:301:6:301:9 | sink |
|
||||||
| tests.cpp:284:10:284:11 | mc |
|
| tests.cpp:301:19:301:20 | mc |
|
||||||
| tests.cpp:284:14:284:16 | mc2 |
|
| tests.cpp:304:8:304:8 | operator= |
|
||||||
| tests.cpp:284:19:284:21 | mc3 |
|
| tests.cpp:304:8:304:8 | operator= |
|
||||||
| tests.cpp:284:24:284:26 | mc4 |
|
| tests.cpp:304:8:304:14 | MyClass |
|
||||||
| tests.cpp:284:29:284:31 | mc5 |
|
| tests.cpp:307:8:307:33 | namespaceMemberMadSinkArg0 |
|
||||||
| tests.cpp:284:34:284:36 | mc6 |
|
| tests.cpp:307:39:307:39 | x |
|
||||||
| tests.cpp:284:39:284:41 | mc7 |
|
| tests.cpp:308:15:308:46 | namespaceStaticMemberMadSinkArg0 |
|
||||||
| tests.cpp:284:44:284:46 | mc8 |
|
| tests.cpp:308:52:308:52 | x |
|
||||||
| tests.cpp:284:49:284:51 | mc9 |
|
| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
|
||||||
| tests.cpp:284:54:284:57 | mc10 |
|
| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
|
||||||
| tests.cpp:284:60:284:63 | mc11 |
|
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
|
||||||
| tests.cpp:285:11:285:13 | ptr |
|
| tests.cpp:317:22:317:28 | source3 |
|
||||||
| tests.cpp:285:17:285:23 | mc4_ptr |
|
| tests.cpp:319:6:319:23 | test_class_members |
|
||||||
| tests.cpp:286:17:286:19 | mdc |
|
| tests.cpp:320:10:320:11 | mc |
|
||||||
| tests.cpp:287:23:287:25 | mnc |
|
| tests.cpp:320:14:320:16 | mc2 |
|
||||||
| tests.cpp:287:28:287:31 | mnc2 |
|
| tests.cpp:320:19:320:21 | mc3 |
|
||||||
| tests.cpp:288:24:288:31 | mnc2_ptr |
|
| tests.cpp:320:24:320:26 | mc4 |
|
||||||
| tests.cpp:294:6:294:6 | a |
|
| tests.cpp:320:29:320:31 | mc5 |
|
||||||
| tests.cpp:387:8:387:8 | operator= |
|
| tests.cpp:320:34:320:36 | mc6 |
|
||||||
| tests.cpp:387:8:387:8 | operator= |
|
| tests.cpp:320:39:320:41 | mc7 |
|
||||||
| tests.cpp:387:8:387:14 | intPair |
|
| tests.cpp:320:44:320:46 | mc8 |
|
||||||
| tests.cpp:388:6:388:10 | first |
|
| tests.cpp:320:49:320:51 | mc9 |
|
||||||
| tests.cpp:389:6:389:11 | second |
|
| tests.cpp:320:54:320:57 | mc10 |
|
||||||
| tests.cpp:392:5:392:29 | madCallArg0ReturnToReturn |
|
| tests.cpp:320:60:320:63 | mc11 |
|
||||||
| tests.cpp:392:37:392:43 | fun_ptr |
|
| tests.cpp:321:11:321:13 | ptr |
|
||||||
| tests.cpp:393:9:393:38 | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:321:17:321:23 | mc4_ptr |
|
||||||
| tests.cpp:393:46:393:52 | fun_ptr |
|
| tests.cpp:322:17:322:19 | mdc |
|
||||||
| tests.cpp:394:6:394:25 | madCallArg0WithValue |
|
| tests.cpp:323:23:323:25 | mnc |
|
||||||
| tests.cpp:394:34:394:40 | fun_ptr |
|
| tests.cpp:323:28:323:31 | mnc2 |
|
||||||
| tests.cpp:394:53:394:57 | value |
|
| tests.cpp:324:24:324:31 | mnc2_ptr |
|
||||||
| tests.cpp:395:5:395:36 | madCallReturnValueIgnoreFunction |
|
| tests.cpp:330:6:330:6 | a |
|
||||||
| tests.cpp:395:45:395:51 | fun_ptr |
|
| tests.cpp:429:8:429:8 | operator= |
|
||||||
| tests.cpp:395:64:395:68 | value |
|
| tests.cpp:429:8:429:8 | operator= |
|
||||||
| tests.cpp:397:5:397:14 | getTainted |
|
| tests.cpp:429:8:429:14 | intPair |
|
||||||
| tests.cpp:398:6:398:13 | useValue |
|
| tests.cpp:430:6:430:10 | first |
|
||||||
| tests.cpp:398:19:398:19 | x |
|
| tests.cpp:431:6:431:11 | second |
|
||||||
| tests.cpp:399:6:399:17 | dontUseValue |
|
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:399:23:399:23 | x |
|
| tests.cpp:434:37:434:43 | fun_ptr |
|
||||||
| tests.cpp:401:6:401:27 | test_function_pointers |
|
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:414:19:414:19 | X |
|
| tests.cpp:435:46:435:52 | fun_ptr |
|
||||||
| tests.cpp:415:8:415:35 | StructWithTypedefInParameter<X> |
|
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
|
||||||
| tests.cpp:415:8:415:35 | StructWithTypedefInParameter<int> |
|
| tests.cpp:436:34:436:40 | fun_ptr |
|
||||||
| tests.cpp:416:12:416:15 | Type |
|
| tests.cpp:436:53:436:57 | value |
|
||||||
| tests.cpp:417:5:417:31 | parameter_ref_to_return_ref |
|
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
|
||||||
| tests.cpp:417:5:417:31 | parameter_ref_to_return_ref |
|
| tests.cpp:437:45:437:51 | fun_ptr |
|
||||||
| tests.cpp:417:45:417:45 | x |
|
| tests.cpp:437:64:437:68 | value |
|
||||||
| tests.cpp:417:45:417:45 | x |
|
| tests.cpp:439:5:439:14 | getTainted |
|
||||||
| tests.cpp:420:6:420:37 | test_parameter_ref_to_return_ref |
|
| tests.cpp:440:6:440:13 | useValue |
|
||||||
| tests.cpp:421:6:421:6 | x |
|
| tests.cpp:440:19:440:19 | x |
|
||||||
| tests.cpp:422:36:422:36 | s |
|
| tests.cpp:441:6:441:17 | dontUseValue |
|
||||||
| tests.cpp:423:6:423:6 | y |
|
| tests.cpp:441:23:441:23 | x |
|
||||||
| tests.cpp:427:7:427:9 | INT |
|
| tests.cpp:443:6:443:27 | test_function_pointers |
|
||||||
| tests.cpp:429:5:429:17 | receive_array |
|
| tests.cpp:456:19:456:19 | X |
|
||||||
| tests.cpp:429:23:429:23 | a |
|
| tests.cpp:457:8:457:35 | StructWithTypedefInParameter<X> |
|
||||||
| tests.cpp:431:6:431:23 | test_receive_array |
|
| tests.cpp:457:8:457:35 | StructWithTypedefInParameter<int> |
|
||||||
| tests.cpp:432:6:432:6 | x |
|
| tests.cpp:458:12:458:15 | Type |
|
||||||
| tests.cpp:433:6:433:10 | array |
|
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
|
||||||
| tests.cpp:434:6:434:6 | y |
|
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
|
||||||
|
| tests.cpp:459:45:459:45 | x |
|
||||||
|
| tests.cpp:459:45:459:45 | x |
|
||||||
|
| tests.cpp:462:6:462:37 | test_parameter_ref_to_return_ref |
|
||||||
|
| tests.cpp:463:6:463:6 | x |
|
||||||
|
| tests.cpp:464:36:464:36 | s |
|
||||||
|
| tests.cpp:465:6:465:6 | y |
|
||||||
|
| tests.cpp:469:7:469:9 | INT |
|
||||||
|
| tests.cpp:471:5:471:17 | receive_array |
|
||||||
|
| tests.cpp:471:23:471:23 | a |
|
||||||
|
| tests.cpp:473:6:473:23 | test_receive_array |
|
||||||
|
| tests.cpp:474:6:474:6 | x |
|
||||||
|
| tests.cpp:475:6:475:10 | array |
|
||||||
|
| tests.cpp:476:6:476:6 | y |
|
||||||
flowSummaryNode
|
flowSummaryNode
|
||||||
| tests.cpp:127:5:127:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
|
| tests.cpp:144:5:144:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
|
||||||
| tests.cpp:127:5:127:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
|
| tests.cpp:144:5:144:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
|
||||||
| tests.cpp:128:6:128:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
|
| tests.cpp:145:6:145:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
|
||||||
| tests.cpp:128:6:128:28 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
|
| tests.cpp:145:6:145:28 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
|
||||||
| tests.cpp:130:5:130:28 | [summary param] 0 in madArg0ToReturnValueFlow | ParameterNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
|
| tests.cpp:147:5:147:28 | [summary param] 0 in madArg0ToReturnValueFlow | ParameterNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
|
||||||
| tests.cpp:130:5:130:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | ReturnNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
|
| tests.cpp:147:5:147:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | ReturnNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
|
||||||
| tests.cpp:131:5:131:27 | [summary param] *0 in madArg0IndirectToReturn | ParameterNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
|
| tests.cpp:148:5:148:27 | [summary param] *0 in madArg0IndirectToReturn | ParameterNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
|
||||||
| tests.cpp:131:5:131:27 | [summary] to write: ReturnValue in madArg0IndirectToReturn | ReturnNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
|
| tests.cpp:148:5:148:27 | [summary] to write: ReturnValue in madArg0IndirectToReturn | ReturnNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
|
||||||
| tests.cpp:132:5:132:33 | [summary param] **0 in madArg0DoubleIndirectToReturn | ParameterNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
|
| tests.cpp:149:5:149:33 | [summary param] **0 in madArg0DoubleIndirectToReturn | ParameterNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
|
||||||
| tests.cpp:132:5:132:33 | [summary] to write: ReturnValue in madArg0DoubleIndirectToReturn | ReturnNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
|
| tests.cpp:149:5:149:33 | [summary] to write: ReturnValue in madArg0DoubleIndirectToReturn | ReturnNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
|
||||||
| tests.cpp:133:5:133:30 | [summary param] 0 in madArg0NotIndirectToReturn | ParameterNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
|
| tests.cpp:150:5:150:30 | [summary param] 0 in madArg0NotIndirectToReturn | ParameterNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
|
||||||
| tests.cpp:133:5:133:30 | [summary] to write: ReturnValue in madArg0NotIndirectToReturn | ReturnNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
|
| tests.cpp:150:5:150:30 | [summary] to write: ReturnValue in madArg0NotIndirectToReturn | ReturnNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
|
||||||
| tests.cpp:134:6:134:26 | [summary param] 0 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
| tests.cpp:151:6:151:26 | [summary param] 0 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
||||||
| tests.cpp:134:6:134:26 | [summary param] *1 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
| tests.cpp:151:6:151:26 | [summary param] *1 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
||||||
| tests.cpp:134:6:134:26 | [summary] to write: Argument[*1] in madArg0ToArg1Indirect | PostUpdateNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
| tests.cpp:151:6:151:26 | [summary] to write: Argument[*1] in madArg0ToArg1Indirect | PostUpdateNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
||||||
| tests.cpp:135:6:135:34 | [summary param] *0 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
| tests.cpp:152:6:152:34 | [summary param] *0 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
||||||
| tests.cpp:135:6:135:34 | [summary param] *1 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
| tests.cpp:152:6:152:34 | [summary param] *1 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
||||||
| tests.cpp:135:6:135:34 | [summary] to write: Argument[*1] in madArg0IndirectToArg1Indirect | PostUpdateNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
| tests.cpp:152:6:152:34 | [summary] to write: Argument[*1] in madArg0IndirectToArg1Indirect | PostUpdateNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
||||||
| tests.cpp:136:5:136:18 | [summary param] 2 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
| tests.cpp:153:5:153:18 | [summary param] 2 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
||||||
| tests.cpp:136:5:136:18 | [summary param] *0 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
| tests.cpp:153:5:153:18 | [summary param] *0 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
||||||
| tests.cpp:136:5:136:18 | [summary param] *1 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
| tests.cpp:153:5:153:18 | [summary param] *1 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
||||||
| tests.cpp:136:5:136:18 | [summary] to write: ReturnValue in madArgsComplex | ReturnNode | madArgsComplex | madArgsComplex |
|
| tests.cpp:153:5:153:18 | [summary] to write: ReturnValue in madArgsComplex | ReturnNode | madArgsComplex | madArgsComplex |
|
||||||
| tests.cpp:138:5:138:28 | [summary param] 2 in madAndImplementedComplex | ParameterNode | madAndImplementedComplex | madAndImplementedComplex |
|
| tests.cpp:155:5:155:28 | [summary param] 2 in madAndImplementedComplex | ParameterNode | madAndImplementedComplex | madAndImplementedComplex |
|
||||||
| tests.cpp:138:5:138:28 | [summary] to write: ReturnValue in madAndImplementedComplex | ReturnNode | madAndImplementedComplex | madAndImplementedComplex |
|
| tests.cpp:155:5:155:28 | [summary] to write: ReturnValue in madAndImplementedComplex | ReturnNode | madAndImplementedComplex | madAndImplementedComplex |
|
||||||
| tests.cpp:143:5:143:24 | [summary param] 0 in madArg0FieldToReturn | ParameterNode | madArg0FieldToReturn | madArg0FieldToReturn |
|
| tests.cpp:160:5:160:24 | [summary param] 0 in madArg0FieldToReturn | ParameterNode | madArg0FieldToReturn | madArg0FieldToReturn |
|
||||||
| tests.cpp:143:5:143:24 | [summary] read: Argument[0].Field[MyContainer::value]/Field[value] in madArg0FieldToReturn | | madArg0FieldToReturn | madArg0FieldToReturn |
|
| tests.cpp:160:5:160:24 | [summary] read: Argument[0].Field[MyContainer::value]/Field[value] in madArg0FieldToReturn | | madArg0FieldToReturn | madArg0FieldToReturn |
|
||||||
| tests.cpp:143:5:143:24 | [summary] to write: ReturnValue in madArg0FieldToReturn | ReturnNode | madArg0FieldToReturn | madArg0FieldToReturn |
|
| tests.cpp:160:5:160:24 | [summary] to write: ReturnValue in madArg0FieldToReturn | ReturnNode | madArg0FieldToReturn | madArg0FieldToReturn |
|
||||||
| tests.cpp:144:5:144:32 | [summary param] *0 in madArg0IndirectFieldToReturn | ParameterNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
| tests.cpp:161:5:161:32 | [summary param] *0 in madArg0IndirectFieldToReturn | ParameterNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
||||||
| tests.cpp:144:5:144:32 | [summary] read: Argument[*0].Field[MyContainer::value]/Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
| tests.cpp:161:5:161:32 | [summary] read: Argument[*0].Field[MyContainer::value]/Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
||||||
| tests.cpp:144:5:144:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
| tests.cpp:161:5:161:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
||||||
| tests.cpp:145:5:145:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
| tests.cpp:162:5:162:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
||||||
| tests.cpp:145:5:145:32 | [summary] read: Argument[0].Field[*MyContainer::ptr]/Field[*ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
| tests.cpp:162:5:162:32 | [summary] read: Argument[0].Field[*MyContainer::ptr]/Field[*ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
||||||
| tests.cpp:145:5:145:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
| tests.cpp:162:5:162:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
||||||
| tests.cpp:146:13:146:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
|
| tests.cpp:163:13:163:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
|
||||||
| tests.cpp:146:13:146:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
|
| tests.cpp:163:13:163:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
|
||||||
| tests.cpp:146:13:146:32 | [summary] to write: ReturnValue.Field[MyContainer::value]/Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
|
| tests.cpp:163:13:163:32 | [summary] to write: ReturnValue.Field[MyContainer::value]/Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
|
||||||
| tests.cpp:147:14:147:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
| tests.cpp:164:14:164:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
||||||
| tests.cpp:147:14:147:41 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
| tests.cpp:164:14:164:41 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
||||||
| tests.cpp:147:14:147:41 | [summary] to write: ReturnValue[*].Field[MyContainer::value]/Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
| tests.cpp:164:14:164:41 | [summary] to write: ReturnValue[*].Field[MyContainer::value]/Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
||||||
| tests.cpp:148:13:148:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
| tests.cpp:165:13:165:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
||||||
| tests.cpp:148:13:148:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
| tests.cpp:165:13:165:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
||||||
| tests.cpp:148:13:148:40 | [summary] to write: ReturnValue.Field[*MyContainer::ptr]/Field[*ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
| tests.cpp:165:13:165:40 | [summary] to write: ReturnValue.Field[*MyContainer::ptr]/Field[*ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
||||||
| tests.cpp:250:7:250:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
|
| tests.cpp:284:7:284:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
|
||||||
| tests.cpp:250:7:250:19 | [summary param] this in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
|
| tests.cpp:284:7:284:19 | [summary param] this in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
|
||||||
| tests.cpp:250:7:250:19 | [summary] to write: Argument[this] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
|
| tests.cpp:284:7:284:19 | [summary] to write: Argument[this] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
|
||||||
| tests.cpp:251:6:251:20 | [summary param] this in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
|
| tests.cpp:285:6:285:20 | [summary param] this in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
|
||||||
| tests.cpp:251:6:251:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
|
| tests.cpp:285:6:285:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
|
||||||
| tests.cpp:253:7:253:20 | [summary param] 0 in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
|
| tests.cpp:287:7:287:20 | [summary param] 0 in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
|
||||||
| tests.cpp:253:7:253:20 | [summary param] this in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
|
| tests.cpp:287:7:287:20 | [summary param] this in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
|
||||||
| tests.cpp:253:7:253:20 | [summary] to write: Argument[this] in madArg0ToField | PostUpdateNode | madArg0ToField | madArg0ToField |
|
| tests.cpp:287:7:287:20 | [summary] to write: Argument[this] in madArg0ToField | PostUpdateNode | madArg0ToField | madArg0ToField |
|
||||||
| tests.cpp:253:7:253:20 | [summary] to write: Argument[this].Field[MyClass::val]/Field[val] in madArg0ToField | | madArg0ToField | madArg0ToField |
|
| tests.cpp:287:7:287:20 | [summary] to write: Argument[this].Field[MyClass::val]/Field[val] in madArg0ToField | | madArg0ToField | madArg0ToField |
|
||||||
| tests.cpp:254:6:254:21 | [summary param] this in madFieldToReturn | ParameterNode | madFieldToReturn | madFieldToReturn |
|
| tests.cpp:288:6:288:21 | [summary param] this in madFieldToReturn | ParameterNode | madFieldToReturn | madFieldToReturn |
|
||||||
| tests.cpp:254:6:254:21 | [summary] read: Argument[this].Field[MyClass::val]/Field[val] in madFieldToReturn | | madFieldToReturn | madFieldToReturn |
|
| tests.cpp:288:6:288:21 | [summary] read: Argument[this].Field[MyClass::val]/Field[val] in madFieldToReturn | | madFieldToReturn | madFieldToReturn |
|
||||||
| tests.cpp:254:6:254:21 | [summary] to write: ReturnValue in madFieldToReturn | ReturnNode | madFieldToReturn | madFieldToReturn |
|
| tests.cpp:288:6:288:21 | [summary] to write: ReturnValue in madFieldToReturn | ReturnNode | madFieldToReturn | madFieldToReturn |
|
||||||
| tests.cpp:277:7:277:30 | [summary param] this in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
|
| tests.cpp:313:7:313:30 | [summary param] this in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
|
||||||
| tests.cpp:277:7:277:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
|
| tests.cpp:313:7:313:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
|
||||||
| tests.cpp:392:5:392:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
| tests.cpp:434:5:434:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:392:5:392:29 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | PostUpdateNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
| tests.cpp:434:5:434:29 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | PostUpdateNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:392:5:392:29 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturn | OutNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
| tests.cpp:434:5:434:29 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturn | OutNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:392:5:392:29 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | ArgumentNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
| tests.cpp:434:5:434:29 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | ArgumentNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:392:5:392:29 | [summary] to write: ReturnValue in madCallArg0ReturnToReturn | ReturnNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
| tests.cpp:434:5:434:29 | [summary] to write: ReturnValue in madCallArg0ReturnToReturn | ReturnNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||||
| tests.cpp:393:9:393:38 | [summary param] 0 in madCallArg0ReturnToReturnFirst | ParameterNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | [summary param] 0 in madCallArg0ReturnToReturnFirst | ParameterNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:393:9:393:38 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | PostUpdateNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | PostUpdateNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:393:9:393:38 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturnFirst | OutNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturnFirst | OutNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:393:9:393:38 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | ArgumentNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | ArgumentNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:393:9:393:38 | [summary] to write: ReturnValue in madCallArg0ReturnToReturnFirst | ReturnNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | [summary] to write: ReturnValue in madCallArg0ReturnToReturnFirst | ReturnNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:393:9:393:38 | [summary] to write: ReturnValue.Field[first]/Field[intPair::first] in madCallArg0ReturnToReturnFirst | | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
| tests.cpp:435:9:435:38 | [summary] to write: ReturnValue.Field[first]/Field[intPair::first] in madCallArg0ReturnToReturnFirst | | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||||
| tests.cpp:394:6:394:25 | [summary param] 0 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary param] 0 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:394:6:394:25 | [summary param] 1 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary param] 1 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:394:6:394:25 | [summary] read: Argument[0].Parameter[0] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary] read: Argument[0].Parameter[0] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:394:6:394:25 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:394:6:394:25 | [summary] to write: Argument[0].Parameter[0] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary] to write: Argument[0].Parameter[0] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:394:6:394:25 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:394:6:394:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
| tests.cpp:436:6:436:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||||
| tests.cpp:395:5:395:36 | [summary param] 1 in madCallReturnValueIgnoreFunction | ParameterNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
|
| tests.cpp:437:5:437:36 | [summary param] 1 in madCallReturnValueIgnoreFunction | ParameterNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
|
||||||
| tests.cpp:395:5:395:36 | [summary] to write: ReturnValue in madCallReturnValueIgnoreFunction | ReturnNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
|
| tests.cpp:437:5:437:36 | [summary] to write: ReturnValue in madCallReturnValueIgnoreFunction | ReturnNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
|
||||||
| tests.cpp:417:5:417:31 | [summary param] *0 in parameter_ref_to_return_ref | ParameterNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
|
| tests.cpp:459:5:459:31 | [summary param] *0 in parameter_ref_to_return_ref | ParameterNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
|
||||||
| tests.cpp:417:5:417:31 | [summary] to write: ReturnValue[*] in parameter_ref_to_return_ref | ReturnNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
|
| tests.cpp:459:5:459:31 | [summary] to write: ReturnValue[*] in parameter_ref_to_return_ref | ReturnNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
|
||||||
| tests.cpp:429:5:429:17 | [summary param] *0 in receive_array | ParameterNode | receive_array | receive_array |
|
| tests.cpp:471:5:471:17 | [summary param] *0 in receive_array | ParameterNode | receive_array | receive_array |
|
||||||
| tests.cpp:429:5:429:17 | [summary] to write: ReturnValue in receive_array | ReturnNode | receive_array | receive_array |
|
| tests.cpp:471:5:471:17 | [summary] to write: ReturnValue in receive_array | ReturnNode | receive_array | receive_array |
|
||||||
|
|||||||
@@ -11,12 +11,15 @@ extensions:
|
|||||||
- ["", "", False, "remoteMadSourceDoubleIndirect", "", "", "ReturnValue[**]", "remote", "manual"]
|
- ["", "", False, "remoteMadSourceDoubleIndirect", "", "", "ReturnValue[**]", "remote", "manual"]
|
||||||
- ["", "", False, "remoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
|
- ["", "", False, "remoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
|
||||||
- ["", "", False, "remoteMadSourceIndirectArg1", "", "", "Argument[*1]", "remote", "manual"]
|
- ["", "", False, "remoteMadSourceIndirectArg1", "", "", "Argument[*1]", "remote", "manual"]
|
||||||
|
- ["", "", False, "remoteMadSourceVar", "", "", "", "remote", "manual"]
|
||||||
|
- ["", "", False, "remoteMadSourceVarIndirect", "", "", "*", "remote", "manual"] # we can't express this source/sink correctly at present, "*" is not a valid access path
|
||||||
- ["", "", False, "remoteMadSourceParam0", "", "", "Parameter[0]", "remote", "manual"]
|
- ["", "", False, "remoteMadSourceParam0", "", "", "Parameter[0]", "remote", "manual"]
|
||||||
- ["MyNamespace", "", False, "namespaceLocalMadSource", "", "", "ReturnValue", "local", "manual"]
|
- ["MyNamespace", "", False, "namespaceLocalMadSource", "", "", "ReturnValue", "local", "manual"]
|
||||||
- ["MyNamespace", "", False, "namespaceLocalMadSourceVar", "", "", "", "local", "manual"]
|
- ["MyNamespace", "", False, "namespaceLocalMadSourceVar", "", "", "", "local", "manual"]
|
||||||
- ["MyNamespace::MyNamespace2", "", False, "namespace2LocalMadSource", "", "", "ReturnValue", "local", "manual"]
|
- ["MyNamespace::MyNamespace2", "", False, "namespace2LocalMadSource", "", "", "ReturnValue", "local", "manual"]
|
||||||
- ["", "MyClass", True, "memberRemoteMadSource", "", "", "ReturnValue", "remote", "manual"]
|
- ["", "MyClass", True, "memberRemoteMadSource", "", "", "ReturnValue", "remote", "manual"]
|
||||||
- ["", "MyClass", True, "memberRemoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
|
- ["", "MyClass", True, "memberRemoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
|
||||||
|
- ["", "MyClass", True, "memberRemoteMadSourceVar", "", "", "", "remote", "manual"]
|
||||||
- ["", "MyClass", True, "subtypeRemoteMadSource1", "", "", "ReturnValue", "remote", "manual"]
|
- ["", "MyClass", True, "subtypeRemoteMadSource1", "", "", "ReturnValue", "remote", "manual"]
|
||||||
- ["", "MyClass", False, "subtypeNonSource", "", "", "ReturnValue", "remote", "manual"] # the tests define this in MyDerivedClass, so it should *not* be recongized as a source
|
- ["", "MyClass", False, "subtypeNonSource", "", "", "ReturnValue", "remote", "manual"] # the tests define this in MyDerivedClass, so it should *not* be recongized as a source
|
||||||
- ["", "MyClass", True, "qualifierSource", "", "", "Argument[-1]", "remote", "manual"]
|
- ["", "MyClass", True, "qualifierSource", "", "", "Argument[-1]", "remote", "manual"]
|
||||||
@@ -32,13 +35,18 @@ extensions:
|
|||||||
- ["", "", False, "madSinkArg02", "", "", "Argument[0,2]", "test-sink", "manual"]
|
- ["", "", False, "madSinkArg02", "", "", "Argument[0,2]", "test-sink", "manual"]
|
||||||
- ["", "", False, "madSinkIndirectArg0", "", "", "Argument[*0]", "test-sink", "manual"]
|
- ["", "", False, "madSinkIndirectArg0", "", "", "Argument[*0]", "test-sink", "manual"]
|
||||||
- ["", "", False, "madSinkDoubleIndirectArg0", "", "", "Argument[**0]", "test-sink", "manual"]
|
- ["", "", False, "madSinkDoubleIndirectArg0", "", "", "Argument[**0]", "test-sink", "manual"]
|
||||||
|
- ["", "", False, "madSinkVar", "", "", "", "test-sink", "manual"]
|
||||||
|
- ["", "", False, "madSinkVarIndirect", "", "", "*", "test-sink", "manual"] # we can't express this source/sink correctly at present, "*" is not a valid access path
|
||||||
- ["", "", False, "madSinkParam0", "", "", "Parameter[0]", "test-sink", "manual"]
|
- ["", "", False, "madSinkParam0", "", "", "Parameter[0]", "test-sink", "manual"]
|
||||||
- ["", "MyClass", True, "memberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
|
- ["", "MyClass", True, "memberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
|
||||||
|
- ["", "MyClass", True, "memberMadSinkVar", "", "", "", "test-sink", "manual"]
|
||||||
- ["", "MyClass", True, "qualifierSink", "", "", "Argument[-1]", "test-sink", "manual"]
|
- ["", "MyClass", True, "qualifierSink", "", "", "Argument[-1]", "test-sink", "manual"]
|
||||||
- ["", "MyClass", True, "qualifierArg0Sink", "", "", "Argument[-1..0]", "test-sink", "manual"]
|
- ["", "MyClass", True, "qualifierArg0Sink", "", "", "Argument[-1..0]", "test-sink", "manual"]
|
||||||
- ["", "MyClass", True, "qualifierFieldSink", "", "", "Argument[-1].val", "test-sink", "manual"]
|
- ["", "MyClass", True, "qualifierFieldSink", "", "", "Argument[-1].val", "test-sink", "manual"]
|
||||||
- ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
|
- ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
|
||||||
- ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
|
- ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
|
||||||
|
- ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkVar", "", "", "", "test-sink", "manual"]
|
||||||
|
- ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkVar", "", "", "", "test-sink", "manual"]
|
||||||
- addsTo:
|
- addsTo:
|
||||||
pack: codeql/cpp-all
|
pack: codeql/cpp-all
|
||||||
extensible: summaryModel
|
extensible: summaryModel
|
||||||
@@ -60,6 +68,9 @@ extensions:
|
|||||||
- ["", "", False, "madArg0ToReturnField", "", "", "Argument[0]", "ReturnValue.Field[value]", "taint", "manual"]
|
- ["", "", False, "madArg0ToReturnField", "", "", "Argument[0]", "ReturnValue.Field[value]", "taint", "manual"]
|
||||||
- ["", "", False, "madArg0ToReturnIndirectField", "", "", "Argument[0]", "ReturnValue[*].Field[value]", "taint", "manual"]
|
- ["", "", False, "madArg0ToReturnIndirectField", "", "", "Argument[0]", "ReturnValue[*].Field[value]", "taint", "manual"]
|
||||||
- ["", "", False, "madArg0ToReturnFieldIndirect", "", "", "Argument[0]", "ReturnValue.Field[*ptr]", "taint", "manual"]
|
- ["", "", False, "madArg0ToReturnFieldIndirect", "", "", "Argument[0]", "ReturnValue.Field[*ptr]", "taint", "manual"]
|
||||||
|
- ["", "", False, "madFieldToFieldVar", "", "", "Field[value]", "Field[value2]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[value2]" is not a valid output
|
||||||
|
- ["", "", False, "madFieldToIndirectFieldVar", "", "", "Field[value]", "Field[*ptr]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[*ptr]" is not a valid output
|
||||||
|
- ["", "", False, "madIndirectFieldToFieldVar", "", "", "Field[value]", "Field[value2]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[value2]" is not a valid output
|
||||||
- ["", "MyClass", True, "madArg0ToSelf", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
- ["", "MyClass", True, "madArg0ToSelf", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||||
- ["", "MyClass", True, "madSelfToReturn", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
- ["", "MyClass", True, "madSelfToReturn", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||||
- ["", "MyClass", True, "madArg0ToField", "", "", "Argument[0]", "Argument[-1].Field[val]", "taint", "manual"]
|
- ["", "MyClass", True, "madArg0ToField", "", "", "Argument[0]", "Argument[-1].Field[val]", "taint", "manual"]
|
||||||
|
|||||||
@@ -17,8 +17,13 @@ int *remoteMadSourceIndirect(); // $ interpretElement
|
|||||||
int **remoteMadSourceDoubleIndirect(); // $ interpretElement
|
int **remoteMadSourceDoubleIndirect(); // $ interpretElement
|
||||||
void remoteMadSourceIndirectArg0(int *x, int *y); // $ interpretElement
|
void remoteMadSourceIndirectArg0(int *x, int *y); // $ interpretElement
|
||||||
void remoteMadSourceIndirectArg1(int &x, int &y); // $ interpretElement
|
void remoteMadSourceIndirectArg1(int &x, int &y); // $ interpretElement
|
||||||
|
int remoteMadSourceVar; // $ interpretElement
|
||||||
|
int *remoteMadSourceVarIndirect; // $ interpretElement
|
||||||
|
|
||||||
namespace MyNamespace {
|
namespace MyNamespace {
|
||||||
|
int namespaceLocalMadSource(); // $ interpretElement
|
||||||
|
int namespaceLocalMadSourceVar; // $ interpretElement
|
||||||
|
|
||||||
namespace MyNamespace2 {
|
namespace MyNamespace2 {
|
||||||
int namespace2LocalMadSource(); // $ interpretElement
|
int namespace2LocalMadSource(); // $ interpretElement
|
||||||
}
|
}
|
||||||
@@ -64,9 +69,14 @@ void test_sources() {
|
|||||||
sink(c);
|
sink(c);
|
||||||
sink(d); // $ ir
|
sink(d); // $ ir
|
||||||
|
|
||||||
|
sink(remoteMadSourceVar); // $ ir
|
||||||
|
sink(*remoteMadSourceVarIndirect); // $ MISSING: ir
|
||||||
|
|
||||||
int e = localMadSource();
|
int e = localMadSource();
|
||||||
sink(e); // $ ir
|
sink(e); // $ ir
|
||||||
|
|
||||||
|
sink(MyNamespace::namespaceLocalMadSource()); // $ ir
|
||||||
|
sink(MyNamespace::namespaceLocalMadSourceVar); // $ ir
|
||||||
sink(MyNamespace::MyNamespace2::namespace2LocalMadSource()); // $ ir
|
sink(MyNamespace::MyNamespace2::namespace2LocalMadSource()); // $ ir
|
||||||
sink(MyNamespace::localMadSource()); // $ (the MyNamespace version of this function is not a source)
|
sink(MyNamespace::localMadSource()); // $ (the MyNamespace version of this function is not a source)
|
||||||
sink(namespaceLocalMadSource()); // (the global namespace version of this function is not a source)
|
sink(namespaceLocalMadSource()); // (the global namespace version of this function is not a source)
|
||||||
@@ -86,8 +96,8 @@ void madSinkArg01(int x, int y, int z); // $ interpretElement
|
|||||||
void madSinkArg02(int x, int y, int z); // $ interpretElement
|
void madSinkArg02(int x, int y, int z); // $ interpretElement
|
||||||
void madSinkIndirectArg0(int *x); // $ interpretElement
|
void madSinkIndirectArg0(int *x); // $ interpretElement
|
||||||
void madSinkDoubleIndirectArg0(int **x); // $ interpretElement
|
void madSinkDoubleIndirectArg0(int **x); // $ interpretElement
|
||||||
|
int madSinkVar; // $ interpretElement
|
||||||
|
int *madSinkVarIndirect; // $ interpretElement
|
||||||
|
|
||||||
void test_sinks() {
|
void test_sinks() {
|
||||||
// test sinks
|
// test sinks
|
||||||
@@ -108,8 +118,15 @@ void test_sinks() {
|
|||||||
madSinkIndirectArg0(&a); // $ ir
|
madSinkIndirectArg0(&a); // $ ir
|
||||||
madSinkIndirectArg0(a_ptr); // $ ir
|
madSinkIndirectArg0(a_ptr); // $ ir
|
||||||
madSinkDoubleIndirectArg0(&a_ptr); // $ ir
|
madSinkDoubleIndirectArg0(&a_ptr); // $ ir
|
||||||
|
|
||||||
|
madSinkVar = source(); // $ ir
|
||||||
|
|
||||||
|
// test sources + sinks together
|
||||||
|
|
||||||
madSinkArg0(localMadSource()); // $ ir
|
madSinkArg0(localMadSource()); // $ ir
|
||||||
madSinkIndirectArg0(remoteMadSourceIndirect()); // $ ir
|
madSinkIndirectArg0(remoteMadSourceIndirect()); // $ ir
|
||||||
|
madSinkVar = remoteMadSourceVar; // $ ir
|
||||||
|
*madSinkVarIndirect = remoteMadSourceVar; // $ MISSING: ir
|
||||||
}
|
}
|
||||||
|
|
||||||
void madSinkParam0(int x) { // $ interpretElement
|
void madSinkParam0(int x) { // $ interpretElement
|
||||||
@@ -147,6 +164,10 @@ MyContainer madArg0ToReturnField(int x); // $ interpretElement
|
|||||||
MyContainer *madArg0ToReturnIndirectField(int x); // $ interpretElement
|
MyContainer *madArg0ToReturnIndirectField(int x); // $ interpretElement
|
||||||
MyContainer madArg0ToReturnFieldIndirect(int x); // $ interpretElement
|
MyContainer madArg0ToReturnFieldIndirect(int x); // $ interpretElement
|
||||||
|
|
||||||
|
MyContainer madFieldToFieldVar; // $ interpretElement
|
||||||
|
MyContainer madFieldToIndirectFieldVar; // $ interpretElement
|
||||||
|
MyContainer *madIndirectFieldToFieldVar; // $ interpretElement
|
||||||
|
|
||||||
void test_summaries() {
|
void test_summaries() {
|
||||||
// test summaries
|
// test summaries
|
||||||
|
|
||||||
@@ -220,6 +241,19 @@ void test_summaries() {
|
|||||||
int *rtn2_ptr = rtn2.ptr;
|
int *rtn2_ptr = rtn2.ptr;
|
||||||
sink(*rtn2_ptr); // $ ir
|
sink(*rtn2_ptr); // $ ir
|
||||||
|
|
||||||
|
// test global variable summaries
|
||||||
|
|
||||||
|
madFieldToFieldVar.value = source();
|
||||||
|
sink(madFieldToFieldVar.value2); // $ MISSING: ir
|
||||||
|
|
||||||
|
madFieldToIndirectFieldVar.value = source();
|
||||||
|
sink(madFieldToIndirectFieldVar.ptr);
|
||||||
|
sink(*(madFieldToIndirectFieldVar.ptr)); // $ MISSING: ir
|
||||||
|
|
||||||
|
madIndirectFieldToFieldVar->value = source();
|
||||||
|
sink((*madIndirectFieldToFieldVar).value2); // $ MISSING: ir
|
||||||
|
sink(madIndirectFieldToFieldVar->value2); // $ MISSING: ir
|
||||||
|
|
||||||
// test source + sinks + summaries together
|
// test source + sinks + summaries together
|
||||||
|
|
||||||
madSinkArg0(madArg0ToReturn(remoteMadSource())); // $ ir
|
madSinkArg0(madArg0ToReturn(remoteMadSource())); // $ ir
|
||||||
@@ -235,13 +269,13 @@ public:
|
|||||||
// sources
|
// sources
|
||||||
int memberRemoteMadSource(); // $ interpretElement
|
int memberRemoteMadSource(); // $ interpretElement
|
||||||
void memberRemoteMadSourceIndirectArg0(int *x); // $ interpretElement
|
void memberRemoteMadSourceIndirectArg0(int *x); // $ interpretElement
|
||||||
|
int memberRemoteMadSourceVar; // $ interpretElement
|
||||||
void qualifierSource(); // $ interpretElement
|
void qualifierSource(); // $ interpretElement
|
||||||
void qualifierFieldSource(); // $ interpretElement
|
void qualifierFieldSource(); // $ interpretElement
|
||||||
|
|
||||||
// sinks
|
// sinks
|
||||||
void memberMadSinkArg0(int x); // $ interpretElement
|
void memberMadSinkArg0(int x); // $ interpretElement
|
||||||
|
int memberMadSinkVar; // $ interpretElement
|
||||||
void qualifierSink(); // $ interpretElement
|
void qualifierSink(); // $ interpretElement
|
||||||
void qualifierArg0Sink(int x); // $ interpretElement
|
void qualifierArg0Sink(int x); // $ interpretElement
|
||||||
void qualifierFieldSink(); // $ interpretElement
|
void qualifierFieldSink(); // $ interpretElement
|
||||||
@@ -272,6 +306,8 @@ namespace MyNamespace {
|
|||||||
// sinks
|
// sinks
|
||||||
void namespaceMemberMadSinkArg0(int x); // $ interpretElement
|
void namespaceMemberMadSinkArg0(int x); // $ interpretElement
|
||||||
static void namespaceStaticMemberMadSinkArg0(int x); // $ interpretElement
|
static void namespaceStaticMemberMadSinkArg0(int x); // $ interpretElement
|
||||||
|
int namespaceMemberMadSinkVar; // $ interpretElement
|
||||||
|
static int namespaceStaticMemberMadSinkVar; // $ interpretElement
|
||||||
|
|
||||||
// summaries
|
// summaries
|
||||||
int namespaceMadSelfToReturn(); // $ interpretElement
|
int namespaceMadSelfToReturn(); // $ interpretElement
|
||||||
@@ -295,6 +331,8 @@ void test_class_members() {
|
|||||||
mc.memberRemoteMadSourceIndirectArg0(&a);
|
mc.memberRemoteMadSourceIndirectArg0(&a);
|
||||||
sink(a); // $ ir
|
sink(a); // $ ir
|
||||||
|
|
||||||
|
sink(mc.memberRemoteMadSourceVar); // $ ir
|
||||||
|
|
||||||
// test subtype sources
|
// test subtype sources
|
||||||
|
|
||||||
sink(mdc.memberRemoteMadSource()); // $ ir
|
sink(mdc.memberRemoteMadSource()); // $ ir
|
||||||
@@ -306,8 +344,12 @@ void test_class_members() {
|
|||||||
|
|
||||||
mc.memberMadSinkArg0(source()); // $ ir
|
mc.memberMadSinkArg0(source()); // $ ir
|
||||||
|
|
||||||
|
mc.memberMadSinkVar = source(); // $ ir
|
||||||
|
|
||||||
mnc.namespaceMemberMadSinkArg0(source()); // $ ir
|
mnc.namespaceMemberMadSinkArg0(source()); // $ ir
|
||||||
MyNamespace::MyClass::namespaceStaticMemberMadSinkArg0(source()); // $ ir
|
MyNamespace::MyClass::namespaceStaticMemberMadSinkArg0(source()); // $ ir
|
||||||
|
mnc.namespaceMemberMadSinkVar = source(); // $ ir
|
||||||
|
MyNamespace::MyClass::namespaceStaticMemberMadSinkVar = source(); // $ ir
|
||||||
|
|
||||||
// test class member summaries
|
// test class member summaries
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main() {}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": {
|
|
||||||
"version": "9.0.201"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
| code/Program.cs:0:0:0:0 | code/Program.cs | |
|
|
||||||
| code/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs:0:0:0:0 | code/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs | |
|
|
||||||
| code/obj/Debug/net9.0/dotnet_build.AssemblyInfo.cs:0:0:0:0 | code/obj/Debug/net9.0/dotnet_build.AssemblyInfo.cs | |
|
|
||||||
| code/obj/Debug/net9.0/dotnet_build.GlobalUsings.g.cs:0:0:0:0 | code/obj/Debug/net9.0/dotnet_build.GlobalUsings.g.cs | |
|
|
||||||
| code/obj/Debug/net9.0/dotnet_build.dll:0:0:0:0 | code/obj/Debug/net9.0/dotnet_build.dll | |
|
|
||||||
| file://:0:0:0:0 | | |
|
|
||||||
| file://Z:/dotnet_build.csproj:0:0:0:0 | Z:/dotnet_build.csproj | relative |
|
|
||||||
| file://Z:/obj/dotnet_build.csproj.nuget.g.props:0:0:0:0 | Z:/obj/dotnet_build.csproj.nuget.g.props | relative |
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import csharp
|
|
||||||
|
|
||||||
from File f, string relative
|
|
||||||
where
|
|
||||||
not f.getURL().matches("file://C:/Program Files/%") and
|
|
||||||
if exists(f.getRelativePath()) then relative = "relative" else relative = ""
|
|
||||||
select f, relative
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import runs_on
|
|
||||||
|
|
||||||
|
|
||||||
@runs_on.windows
|
|
||||||
def test(codeql, csharp, cwd, subst_drive):
|
|
||||||
drive = subst_drive(cwd / "code")
|
|
||||||
codeql.database.create(source_root=drive)
|
|
||||||
@@ -714,7 +714,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
|||||||
) and
|
) and
|
||||||
model = ""
|
model = ""
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CsharpDataFlow>
|
|||||||
|
|
||||||
class SinkBase = Void;
|
class SinkBase = Void;
|
||||||
|
|
||||||
class FlowSummaryCallBase = Void;
|
|
||||||
|
|
||||||
predicate neutralElement(SummarizedCallableBase c, string kind, string provenance, boolean isExact) {
|
predicate neutralElement(SummarizedCallableBase c, string kind, string provenance, boolean isExact) {
|
||||||
interpretNeutral(c, kind, provenance, isExact)
|
interpretNeutral(c, kind, provenance, isExact)
|
||||||
}
|
}
|
||||||
@@ -203,10 +201,6 @@ private module TypesInput implements Impl::Private::TypesInputSig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||||
Impl::Private::SummaryNode getSummaryNode(Node n) {
|
|
||||||
result = n.(FlowSummaryNode).getSummaryNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
||||||
sc = viableCallable(result).asSummarizedCallable()
|
sc = viableCallable(result).asSummarizedCallable()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ private module Cached {
|
|||||||
) and
|
) and
|
||||||
model = ""
|
model = ""
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,6 +186,13 @@ private Expr aspWrittenValue(AspInlineMember m) {
|
|||||||
m.getMember().(Callable).canReturn(result)
|
m.getMember().(Callable).canReturn(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string makeUrl(Location l) {
|
||||||
|
exists(string path, int sl, int sc, int el, int ec |
|
||||||
|
l.hasLocationInfo(path, sl, sc, el, ec) and
|
||||||
|
result = "file://" + path + ":" + sl + ":" + sc + ":" + el + ":" + ec
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sink for writes to properties that are accessed in ASP pages.
|
* A sink for writes to properties that are accessed in ASP pages.
|
||||||
*
|
*
|
||||||
@@ -201,7 +208,10 @@ private class AspxCodeSink extends Sink {
|
|||||||
|
|
||||||
AspxCodeSink() { this.getExpr() = aspWrittenValue(inline) }
|
AspxCodeSink() { this.getExpr() = aspWrittenValue(inline) }
|
||||||
|
|
||||||
override string explanation() { result = "member is accessed inline in an ASPX page" }
|
override string explanation() {
|
||||||
|
result =
|
||||||
|
"member is [[\"accessed inline\"|\"" + makeUrl(inline.getLocation()) + "\"]] in an ASPX page"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A sink for the output stream associated with a `HttpListenerResponse`. */
|
/** A sink for the output stream associated with a `HttpListenerResponse`. */
|
||||||
|
|||||||
@@ -69,26 +69,6 @@ The CodeQL library for Java and Kotlin analysis exposes the following extensible
|
|||||||
|
|
||||||
The extensible predicates are populated using the models defined in data extension files.
|
The extensible predicates are populated using the models defined in data extension files.
|
||||||
|
|
||||||
Specifying types in Java and Kotlin models
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
**Nested and inner classes** are denoted by joining the enclosing type and the nested type with a dollar sign (``$``), for example ``Outer$Inner``. This applies both to the type column and to nested types in a signature. For example, the ``Level`` enum nested inside the ``Logger`` interface, nested inside the ``System`` class, is written as ``System$Logger$Level``:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
- ["java.lang", "System$Logger", True, "log", "(System$Logger$Level,String)", "", "Argument[1]", "log-injection", "manual"]
|
|
||||||
|
|
||||||
**Generics** are erased, so type parameters are removed:
|
|
||||||
|
|
||||||
- In the type column, leave out any type parameters, so ``List<E>`` becomes ``List``.
|
|
||||||
- In the signature, replace each type parameter with its upper bound, or ``Object`` if it has none. So ``T`` from ``<T>`` becomes ``Object``, and ``T`` from ``<T extends Number>`` becomes ``Number``.
|
|
||||||
|
|
||||||
For example, ``forEach`` on ``Iterable<T>`` takes a ``Consumer<? super T>`` argument, so the type is ``Iterable`` and the signature is ``(Consumer)``:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
- ["java.lang", "Iterable", True, "forEach", "(Consumer)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
|
||||||
|
|
||||||
Examples of custom model definitions
|
Examples of custom model definitions
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,,,,,,10,
|
|||||||
k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47,
|
k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47,
|
||||||
k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
|
k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
|
||||||
launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
|
launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
|
||||||
log,43,,16,,,,43,,,,,,,,,,,,,,,,,,,16,
|
log,40,,3,,,,40,,,,,,,,,,,,,,,,,,,3,
|
||||||
math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
|
math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||||
mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14,
|
mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14,
|
||||||
net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100,
|
net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100,
|
||||||
|
|||||||
|
@@ -32,7 +32,7 @@ Go framework & library support
|
|||||||
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
|
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
|
||||||
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
|
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
|
||||||
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
|
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
|
||||||
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,625,127
|
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,124
|
||||||
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
|
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
|
||||||
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
|
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
|
||||||
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
|
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
|
||||||
@@ -74,5 +74,5 @@ Go framework & library support
|
|||||||
`xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2
|
`xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2
|
||||||
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
|
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
|
||||||
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
|
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
|
||||||
Totals,,688,1085,1580
|
Totals,,688,1072,1577
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
func main() {}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
| file://Z:/main.go:0:0:0:0 | Z:/main.go | relative |
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import go
|
|
||||||
|
|
||||||
from File f, string relative
|
|
||||||
where if exists(f.getRelativePath()) then relative = "relative" else relative = ""
|
|
||||||
select f, relative
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import runs_on
|
|
||||||
|
|
||||||
|
|
||||||
@runs_on.windows
|
|
||||||
def test(codeql, go, cwd, subst_drive):
|
|
||||||
drive = subst_drive(cwd / "code")
|
|
||||||
codeql.database.create(command="go build main.go", source_root=drive)
|
|
||||||
@@ -141,7 +141,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
|||||||
any(FunctionModel m).flowStep(nodeFrom, nodeTo) and
|
any(FunctionModel m).flowStep(nodeFrom, nodeTo) and
|
||||||
model = "FunctionModel"
|
model = "FunctionModel"
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::GoDataFlow> {
|
|||||||
|
|
||||||
class SinkBase = Void;
|
class SinkBase = Void;
|
||||||
|
|
||||||
class FlowSummaryCallBase = Void;
|
|
||||||
|
|
||||||
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getFuncDef()) }
|
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getFuncDef()) }
|
||||||
|
|
||||||
predicate neutralElement(
|
predicate neutralElement(
|
||||||
@@ -115,10 +113,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::GoDataFlow> {
|
|||||||
private import Make<Location, DataFlowImplSpecific::GoDataFlow, Input> as Impl
|
private import Make<Location, DataFlowImplSpecific::GoDataFlow, Input> as Impl
|
||||||
|
|
||||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||||
Impl::Private::SummaryNode getSummaryNode(Node n) {
|
|
||||||
result = n.(FlowSummaryNode).getSummaryNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
||||||
exists(DataFlow::CallNode call |
|
exists(DataFlow::CallNode call |
|
||||||
call.asExpr() = result and
|
call.asExpr() = result and
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ private predicate localAdditionalForwardTaintStep(
|
|||||||
or
|
or
|
||||||
any(AdditionalTaintStep a).step(pred, succ) and model = "AdditionalTaintStep"
|
any(AdditionalTaintStep a).step(pred, succ) and model = "AdditionalTaintStep"
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(DataFlowPrivate::FlowSummaryNode)
|
||||||
succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model)
|
.getSummaryNode(), succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -188,8 +188,6 @@ org.apache.hadoop.hive.ql.metadata,1,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,
|
|||||||
org.apache.hc.client5.http.async.methods,84,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,84,,,,,,,,,,,,,,,,,,
|
org.apache.hc.client5.http.async.methods,84,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,84,,,,,,,,,,,,,,,,,,
|
||||||
org.apache.hc.client5.http.classic.methods,37,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37,,,,,,,,,,,,,,,,,,
|
org.apache.hc.client5.http.classic.methods,37,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37,,,,,,,,,,,,,,,,,,
|
||||||
org.apache.hc.client5.http.fluent,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,,,,,,,
|
org.apache.hc.client5.http.fluent,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,,,,,,,
|
||||||
org.apache.hc.client5.http.protocol,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
|
||||||
org.apache.hc.client5.http.utils,,,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,
|
|
||||||
org.apache.hc.core5.benchmark,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,
|
org.apache.hc.core5.benchmark,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,
|
||||||
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||||
org.apache.hc.core5.http,73,2,45,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,72,,,,,,,,,,,,,,,,2,45,
|
org.apache.hc.core5.http,73,2,45,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,72,,,,,,,,,,,,,,,,2,45,
|
||||||
|
|||||||
|
@@ -40,6 +40,6 @@ Java framework & library support
|
|||||||
`Spring <https://spring.io/>`_,``org.springframework.*``,46,494,143,26,,28,14,,35
|
`Spring <https://spring.io/>`_,``org.springframework.*``,46,494,143,26,,28,14,,35
|
||||||
`Thymeleaf <https://www.thymeleaf.org/>`_,``org.thymeleaf``,,2,2,,,,,,
|
`Thymeleaf <https://www.thymeleaf.org/>`_,``org.thymeleaf``,,2,2,,,,,,
|
||||||
`jOOQ <https://www.jooq.org/>`_,``org.jooq``,,,1,,,1,,,
|
`jOOQ <https://www.jooq.org/>`_,``org.jooq``,,,1,,,1,,,
|
||||||
Others,"``actions.osgi``, ``antlr``, ``ch.ethz.ssh2``, ``cn.hutool.core.codec``, ``com.alibaba.com.caucho.hessian.io``, ``com.alibaba.druid.sql``, ``com.alibaba.fastjson2``, ``com.amazonaws.auth``, ``com.auth0.jwt.algorithms``, ``com.azure.identity``, ``com.caucho.burlap.io``, ``com.caucho.hessian.io``, ``com.cedarsoftware.util.io``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.esotericsoftware.yamlbeans``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.microsoft.sqlserver.jdbc``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2``, ``com.sshtools.j2ssh.authentication``, ``com.sun.crypto.provider``, ``com.sun.jndi.ldap``, ``com.sun.net.httpserver``, ``com.sun.net.ssl``, ``com.sun.rowset``, ``com.sun.security.auth.module``, ``com.sun.security.ntlm``, ``com.sun.security.sasl.digest``, ``com.thoughtworks.xstream``, ``com.trilead.ssh2``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``hudson``, ``io.jsonwebtoken``, ``io.undertow.server.handlers.resource``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``liquibase.database.jvm``, ``liquibase.statement.core``, ``net.lingala.zip4j``, ``net.schmizz.sshj``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.avro``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.exec``, ``org.apache.commons.fileupload``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.lang``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.cxf.catalog``, ``org.apache.cxf.common.classloader``, ``org.apache.cxf.common.jaxb``, ``org.apache.cxf.common.logging``, ``org.apache.cxf.configuration.jsse``, ``org.apache.cxf.helpers``, ``org.apache.cxf.resource``, ``org.apache.cxf.staxutils``, ``org.apache.cxf.tools.corba.utils``, ``org.apache.cxf.tools.util``, ``org.apache.cxf.transform``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hadoop.hive.ql.exec``, ``org.apache.hadoop.hive.ql.metadata``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hc.client5.http.protocol``, ``org.apache.hc.client5.http.utils``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.ibatis.mapping``, ``org.apache.log4j``, ``org.apache.shiro.authc``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.shiro.mgt``, ``org.apache.sshd.client.session``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.codehaus.cargo.container.installer``, ``org.dom4j``, ``org.exolab.castor.xml``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.gradle.api.file``, ``org.ho.yaml``, ``org.influxdb``, ``org.jabsorb``, ``org.jboss.vfs``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.keycloak.models.map.storage``, ``org.kohsuke.stapler``, ``org.lastaflute.web``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.owasp.esapi``, ``org.pac4j.jwt.config.encryption``, ``org.pac4j.jwt.config.signature``, ``org.scijava.log``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``software.amazon.awssdk.transfer.s3.model``, ``sun.jvmstat.perfdata.monitor.protocol.local``, ``sun.jvmstat.perfdata.monitor.protocol.rmi``, ``sun.misc``, ``sun.net.ftp``, ``sun.net.www.protocol.http``, ``sun.security.acl``, ``sun.security.jgss.krb5``, ``sun.security.krb5``, ``sun.security.pkcs``, ``sun.security.pkcs11``, ``sun.security.provider``, ``sun.security.ssl``, ``sun.security.x509``, ``sun.tools.jconsole``",127,6042,775,148,6,14,18,,186
|
Others,"``actions.osgi``, ``antlr``, ``ch.ethz.ssh2``, ``cn.hutool.core.codec``, ``com.alibaba.com.caucho.hessian.io``, ``com.alibaba.druid.sql``, ``com.alibaba.fastjson2``, ``com.amazonaws.auth``, ``com.auth0.jwt.algorithms``, ``com.azure.identity``, ``com.caucho.burlap.io``, ``com.caucho.hessian.io``, ``com.cedarsoftware.util.io``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.esotericsoftware.yamlbeans``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.microsoft.sqlserver.jdbc``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2``, ``com.sshtools.j2ssh.authentication``, ``com.sun.crypto.provider``, ``com.sun.jndi.ldap``, ``com.sun.net.httpserver``, ``com.sun.net.ssl``, ``com.sun.rowset``, ``com.sun.security.auth.module``, ``com.sun.security.ntlm``, ``com.sun.security.sasl.digest``, ``com.thoughtworks.xstream``, ``com.trilead.ssh2``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``hudson``, ``io.jsonwebtoken``, ``io.undertow.server.handlers.resource``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``liquibase.database.jvm``, ``liquibase.statement.core``, ``net.lingala.zip4j``, ``net.schmizz.sshj``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.avro``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.exec``, ``org.apache.commons.fileupload``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.lang``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.cxf.catalog``, ``org.apache.cxf.common.classloader``, ``org.apache.cxf.common.jaxb``, ``org.apache.cxf.common.logging``, ``org.apache.cxf.configuration.jsse``, ``org.apache.cxf.helpers``, ``org.apache.cxf.resource``, ``org.apache.cxf.staxutils``, ``org.apache.cxf.tools.corba.utils``, ``org.apache.cxf.tools.util``, ``org.apache.cxf.transform``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hadoop.hive.ql.exec``, ``org.apache.hadoop.hive.ql.metadata``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.ibatis.mapping``, ``org.apache.log4j``, ``org.apache.shiro.authc``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.shiro.mgt``, ``org.apache.sshd.client.session``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.codehaus.cargo.container.installer``, ``org.dom4j``, ``org.exolab.castor.xml``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.gradle.api.file``, ``org.ho.yaml``, ``org.influxdb``, ``org.jabsorb``, ``org.jboss.vfs``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.keycloak.models.map.storage``, ``org.kohsuke.stapler``, ``org.lastaflute.web``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.owasp.esapi``, ``org.pac4j.jwt.config.encryption``, ``org.pac4j.jwt.config.signature``, ``org.scijava.log``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``software.amazon.awssdk.transfer.s3.model``, ``sun.jvmstat.perfdata.monitor.protocol.local``, ``sun.jvmstat.perfdata.monitor.protocol.rmi``, ``sun.misc``, ``sun.net.ftp``, ``sun.net.www.protocol.http``, ``sun.security.acl``, ``sun.security.jgss.krb5``, ``sun.security.krb5``, ``sun.security.pkcs``, ``sun.security.pkcs11``, ``sun.security.provider``, ``sun.security.ssl``, ``sun.security.x509``, ``sun.tools.jconsole``",127,6034,775,148,6,14,18,,186
|
||||||
Totals,,382,26411,2707,421,16,137,33,1,415
|
Totals,,382,26403,2707,421,16,137,33,1,415
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
class Test {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
fun main() {}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
| file://:0:0:0:0 | | |
|
|
||||||
| file://:0:0:0:0 | | |
|
|
||||||
| file://Z:/Test.class:0:0:0:0 | Test | relative |
|
|
||||||
| file://Z:/test1.java:0:0:0:0 | test1 | relative |
|
|
||||||
| file://Z:/test2.kt:0:0:0:0 | test2 | relative |
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import java
|
|
||||||
|
|
||||||
from File f, string relative
|
|
||||||
where
|
|
||||||
not f.getURL().matches("file:///modules/%") and
|
|
||||||
not f.getURL().matches("file:///!unknown-binary-location/kotlin/%") and
|
|
||||||
not f.getURL().matches("%/ql/java/kotlin-extractor/%") and
|
|
||||||
if exists(f.getRelativePath()) then relative = "relative" else relative = ""
|
|
||||||
select f, relative
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import runs_on
|
|
||||||
|
|
||||||
|
|
||||||
@runs_on.windows
|
|
||||||
def test(codeql, java, cwd, subst_drive):
|
|
||||||
drive = subst_drive(cwd / "code")
|
|
||||||
codeql.database.create(command=["javac test1.java", "kotlinc test2.kt"], source_root=drive)
|
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
extensions:
|
extensions:
|
||||||
- addsTo:
|
|
||||||
pack: codeql/java-all
|
|
||||||
extensible: summaryModel
|
|
||||||
data:
|
|
||||||
- ["org.apache.hc.client5.http.protocol", "RedirectLocations", True, "add", "(URI)", "", "Argument[0]", "Argument[this].Element", "value", "hq-manual"]
|
|
||||||
|
|
||||||
- addsTo:
|
- addsTo:
|
||||||
pack: codeql/java-all
|
pack: codeql/java-all
|
||||||
extensible: neutralModel
|
extensible: neutralModel
|
||||||
|
|||||||
6
java/ql/lib/ext/org.apache.hc.client5.http.protocol.yml
Normal file
6
java/ql/lib/ext/org.apache.hc.client5.http.protocol.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/java-all
|
||||||
|
extensible: summaryModel
|
||||||
|
data:
|
||||||
|
- ["org.apache.hc.client5.http.protocol", "RedirectLocations", True, "add", "(URI)", "", "Argument[0]", "Argument[this].Element", "value", "hq-manual"]
|
||||||
@@ -247,8 +247,8 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2, string model) {
|
|||||||
or
|
or
|
||||||
cloneStep(node1, node2) and model = "CloneStep"
|
cloneStep(node1, node2) and model = "CloneStep"
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2.(FlowSummaryNode).getSummaryNode(),
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(),
|
||||||
true, model)
|
node2.(FlowSummaryNode).getSummaryNode(), true, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::JavaDataFlow> {
|
|||||||
|
|
||||||
class SinkBase = Void;
|
class SinkBase = Void;
|
||||||
|
|
||||||
class FlowSummaryCallBase = Void;
|
|
||||||
|
|
||||||
predicate neutralElement(
|
predicate neutralElement(
|
||||||
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
|
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
|
||||||
) {
|
) {
|
||||||
@@ -146,10 +144,6 @@ private module TypesInput implements Impl::Private::TypesInputSig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||||
Impl::Private::SummaryNode getSummaryNode(Node n) {
|
|
||||||
result = n.(FlowSummaryNode).getSummaryNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
||||||
sc = viableCallable(result).asSummarizedCallable()
|
sc = viableCallable(result).asSummarizedCallable()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ private module Cached {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(src.(DataFlowPrivate::FlowSummaryNode)
|
||||||
sink.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model)
|
.getSummaryNode(), sink.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -234,3 +234,8 @@ subpaths
|
|||||||
| use.kt:9:14:9:25 | taint(...) : Closeable | use.kt:9:31:9:36 | it : Closeable | use.kt:9:33:9:34 | it : Closeable | use.kt:9:14:9:36 | use(...) |
|
| use.kt:9:14:9:25 | taint(...) : Closeable | use.kt:9:31:9:36 | it : Closeable | use.kt:9:33:9:34 | it : Closeable | use.kt:9:14:9:36 | use(...) |
|
||||||
| with.kt:7:19:7:30 | taint(...) : String | with.kt:7:33:7:40 | $this$with : String | with.kt:7:35:7:38 | this : String | with.kt:7:14:7:40 | with(...) |
|
| with.kt:7:19:7:30 | taint(...) : String | with.kt:7:33:7:40 | $this$with : String | with.kt:7:35:7:38 | this : String | with.kt:7:14:7:40 | with(...) |
|
||||||
testFailures
|
testFailures
|
||||||
|
| test.kt:28:14:28:21 | getSecond(...) | Unexpected result: hasTaintFlow=a |
|
||||||
|
| test.kt:35:14:35:27 | component1(...) | Unexpected result: hasTaintFlow=d |
|
||||||
|
| test.kt:41:14:41:22 | getSecond(...) | Unexpected result: hasTaintFlow=e |
|
||||||
|
| test.kt:53:14:53:24 | getDuration(...) | Unexpected result: hasTaintFlow=f |
|
||||||
|
| test.kt:58:14:58:29 | component2(...) | Unexpected result: hasTaintFlow=g |
|
||||||
|
|||||||
@@ -25,20 +25,20 @@ class Test {
|
|||||||
val p = Pair(taint("a"), "")
|
val p = Pair(taint("a"), "")
|
||||||
sink(p) // $ hasTaintFlow=a
|
sink(p) // $ hasTaintFlow=a
|
||||||
sink(p.component1()) // $ hasTaintFlow=a
|
sink(p.component1()) // $ hasTaintFlow=a
|
||||||
sink(p.second) // $ SPURIOUS: hasTaintFlow=a
|
sink(p.second)
|
||||||
|
|
||||||
sink(taint("b").capitalize()) // $ hasTaintFlow=b
|
sink(taint("b").capitalize()) // $ hasTaintFlow=b
|
||||||
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
|
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
|
||||||
|
|
||||||
val t = Triple("", taint("d"), "")
|
val t = Triple("", taint("d"), "")
|
||||||
sink(t) // $ hasTaintFlow=d
|
sink(t) // $ hasTaintFlow=d
|
||||||
sink(t.component1()) // $ SPURIOUS: hasTaintFlow=d
|
sink(t.component1())
|
||||||
sink(t.second) // $ hasTaintFlow=d
|
sink(t.second) // $ hasTaintFlow=d
|
||||||
|
|
||||||
val p1 = taint("e") to ""
|
val p1 = taint("e") to ""
|
||||||
sink(p1) // $ hasTaintFlow=e
|
sink(p1) // $ hasTaintFlow=e
|
||||||
sink(p1.component1()) // $ hasTaintFlow=e
|
sink(p1.component1()) // $ hasTaintFlow=e
|
||||||
sink(p1.second) // $ SPURIOUS: hasTaintFlow=e
|
sink(p1.second)
|
||||||
|
|
||||||
val l = p.toList()
|
val l = p.toList()
|
||||||
sink(l) // $ hasTaintFlow=a
|
sink(l) // $ hasTaintFlow=a
|
||||||
@@ -50,12 +50,12 @@ class Test {
|
|||||||
val tv = TimedValue(taint("f"), Duration.parse(""))
|
val tv = TimedValue(taint("f"), Duration.parse(""))
|
||||||
sink(tv) // $ hasTaintFlow=f
|
sink(tv) // $ hasTaintFlow=f
|
||||||
sink(tv.component1()) // $ hasTaintFlow=f
|
sink(tv.component1()) // $ hasTaintFlow=f
|
||||||
sink(tv.duration) // $ SPURIOUS: hasTaintFlow=f
|
sink(tv.duration)
|
||||||
|
|
||||||
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
|
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
|
||||||
sink(mg0) // $ hasTaintFlow=g
|
sink(mg0) // $ hasTaintFlow=g
|
||||||
sink(mg0.value) // $ hasTaintFlow=g
|
sink(mg0.value) // $ hasTaintFlow=g
|
||||||
sink(mg0.component2()) // $ SPURIOUS: hasTaintFlow=g
|
sink(mg0.component2())
|
||||||
|
|
||||||
val iv = IndexedValue<String>(5, taint("h"))
|
val iv = IndexedValue<String>(5, taint("h"))
|
||||||
sink(iv) // $ hasTaintFlow=h
|
sink(iv) // $ hasTaintFlow=h
|
||||||
|
|||||||
@@ -234,3 +234,8 @@ subpaths
|
|||||||
| use.kt:9:14:9:25 | taint(...) : Closeable | use.kt:9:31:9:36 | it : Closeable | use.kt:9:33:9:34 | it : Closeable | use.kt:9:14:9:36 | use(...) |
|
| use.kt:9:14:9:25 | taint(...) : Closeable | use.kt:9:31:9:36 | it : Closeable | use.kt:9:33:9:34 | it : Closeable | use.kt:9:14:9:36 | use(...) |
|
||||||
| with.kt:7:19:7:30 | taint(...) : String | with.kt:7:33:7:40 | $this$with : String | with.kt:7:35:7:38 | this : String | with.kt:7:14:7:40 | with(...) |
|
| with.kt:7:19:7:30 | taint(...) : String | with.kt:7:33:7:40 | $this$with : String | with.kt:7:35:7:38 | this : String | with.kt:7:14:7:40 | with(...) |
|
||||||
testFailures
|
testFailures
|
||||||
|
| test.kt:28:14:28:21 | getSecond(...) | Unexpected result: hasTaintFlow=a |
|
||||||
|
| test.kt:35:14:35:27 | component1(...) | Unexpected result: hasTaintFlow=d |
|
||||||
|
| test.kt:41:14:41:22 | getSecond(...) | Unexpected result: hasTaintFlow=e |
|
||||||
|
| test.kt:53:14:53:24 | getDuration(...) | Unexpected result: hasTaintFlow=f |
|
||||||
|
| test.kt:58:14:58:29 | component2(...) | Unexpected result: hasTaintFlow=g |
|
||||||
|
|||||||
@@ -25,20 +25,20 @@ class Test {
|
|||||||
val p = Pair(taint("a"), "")
|
val p = Pair(taint("a"), "")
|
||||||
sink(p) // $ hasTaintFlow=a
|
sink(p) // $ hasTaintFlow=a
|
||||||
sink(p.component1()) // $ hasTaintFlow=a
|
sink(p.component1()) // $ hasTaintFlow=a
|
||||||
sink(p.second) // $ SPURIOUS: hasTaintFlow=a
|
sink(p.second)
|
||||||
|
|
||||||
sink(taint("b").capitalize()) // $ hasTaintFlow=b
|
sink(taint("b").capitalize()) // $ hasTaintFlow=b
|
||||||
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
|
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
|
||||||
|
|
||||||
val t = Triple("", taint("d"), "")
|
val t = Triple("", taint("d"), "")
|
||||||
sink(t) // $ hasTaintFlow=d
|
sink(t) // $ hasTaintFlow=d
|
||||||
sink(t.component1()) // $ SPURIOUS: hasTaintFlow=d
|
sink(t.component1())
|
||||||
sink(t.second) // $ hasTaintFlow=d
|
sink(t.second) // $ hasTaintFlow=d
|
||||||
|
|
||||||
val p1 = taint("e") to ""
|
val p1 = taint("e") to ""
|
||||||
sink(p1) // $ hasTaintFlow=e
|
sink(p1) // $ hasTaintFlow=e
|
||||||
sink(p1.component1()) // $ hasTaintFlow=e
|
sink(p1.component1()) // $ hasTaintFlow=e
|
||||||
sink(p1.second) // $ SPURIOUS: hasTaintFlow=e
|
sink(p1.second)
|
||||||
|
|
||||||
val l = p.toList()
|
val l = p.toList()
|
||||||
sink(l) // $ hasTaintFlow=a
|
sink(l) // $ hasTaintFlow=a
|
||||||
@@ -50,12 +50,12 @@ class Test {
|
|||||||
val tv = TimedValue(taint("f"), Duration.parse(""))
|
val tv = TimedValue(taint("f"), Duration.parse(""))
|
||||||
sink(tv) // $ hasTaintFlow=f
|
sink(tv) // $ hasTaintFlow=f
|
||||||
sink(tv.component1()) // $ hasTaintFlow=f
|
sink(tv.component1()) // $ hasTaintFlow=f
|
||||||
sink(tv.duration) // $ SPURIOUS: hasTaintFlow=f
|
sink(tv.duration)
|
||||||
|
|
||||||
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
|
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
|
||||||
sink(mg0) // $ hasTaintFlow=g
|
sink(mg0) // $ hasTaintFlow=g
|
||||||
sink(mg0.value) // $ hasTaintFlow=g
|
sink(mg0.value) // $ hasTaintFlow=g
|
||||||
sink(mg0.component2()) // $ SPURIOUS: hasTaintFlow=g
|
sink(mg0.component2())
|
||||||
|
|
||||||
val iv = IndexedValue<String>(5, taint("h"))
|
val iv = IndexedValue<String>(5, taint("h"))
|
||||||
sink(iv) // $ hasTaintFlow=h
|
sink(iv) // $ hasTaintFlow=h
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ predicate taintFlowUpdate(DataFlow::ParameterNode p1, DataFlow::ParameterNode p2
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicate summaryStep(FlowSummaryNode src, FlowSummaryNode sink) {
|
predicate summaryStep(FlowSummaryNode src, FlowSummaryNode sink) {
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink.getSummaryNode(), false, _) or
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(src.getSummaryNode(), sink.getSummaryNode(),
|
||||||
|
false, _) or
|
||||||
FlowSummaryImpl::Private::Steps::summaryReadStep(src.getSummaryNode(), _, sink.getSummaryNode()) or
|
FlowSummaryImpl::Private::Steps::summaryReadStep(src.getSummaryNode(), _, sink.getSummaryNode()) or
|
||||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(src.getSummaryNode(), _, sink.getSummaryNode())
|
FlowSummaryImpl::Private::Steps::summaryStoreStep(src.getSummaryNode(), _, sink.getSummaryNode())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
function interesting() { }
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
0
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
| file://Z:/main.js:0:0:0:0 | Z:/main.js | relative |
|
|
||||||
| file://Z:/test.ts:0:0:0:0 | Z:/test.ts | relative |
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import javascript
|
|
||||||
|
|
||||||
from File f, string relative
|
|
||||||
where
|
|
||||||
not f.getURL().matches("%/target/intree/%") and
|
|
||||||
if exists(f.getRelativePath()) then relative = "relative" else relative = ""
|
|
||||||
select f, relative
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import runs_on
|
|
||||||
|
|
||||||
|
|
||||||
@runs_on.windows
|
|
||||||
def test(codeql, javascript, cwd, subst_drive):
|
|
||||||
drive = subst_drive(cwd / "code")
|
|
||||||
codeql.database.create(source_root=drive)
|
|
||||||
@@ -1212,8 +1212,8 @@ private predicate valuePreservingStep(Node node1, Node node2) {
|
|||||||
or
|
or
|
||||||
node2 = FlowSteps::getThrowTarget(node1)
|
node2 = FlowSteps::getThrowTarget(node1)
|
||||||
or
|
or
|
||||||
FlowSummaryPrivate::Steps::summaryLocalStep(node1, node2.(FlowSummaryNode).getSummaryNode(), true,
|
FlowSummaryPrivate::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(),
|
||||||
_) // TODO: preserve 'model'
|
node2.(FlowSummaryNode).getSummaryNode(), true, _) // TODO: preserve 'model'
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate knownSourceModel(Node sink, string model) { none() }
|
predicate knownSourceModel(Node sink, string model) { none() }
|
||||||
|
|||||||
@@ -142,10 +142,6 @@ string encodeArgumentPosition(ArgumentPosition pos) {
|
|||||||
ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() and Stage::ref() }
|
ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() and Stage::ref() }
|
||||||
|
|
||||||
private module FlowSummaryStepInput implements Private::StepsInputSig {
|
private module FlowSummaryStepInput implements Private::StepsInputSig {
|
||||||
Private::SummaryNode getSummaryNode(DataFlow::Node n) {
|
|
||||||
result = n.(FlowSummaryNode).getSummaryNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay[global]
|
overlay[global]
|
||||||
DataFlowCall getACall(SummarizedCallable sc) {
|
DataFlowCall getACall(SummarizedCallable sc) {
|
||||||
exists(LibraryCallable callable | callable = sc |
|
exists(LibraryCallable callable | callable = sc |
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ cached
|
|||||||
predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
TaintTracking::AdditionalTaintStep::step(node1, node2)
|
TaintTracking::AdditionalTaintStep::step(node1, node2)
|
||||||
or
|
or
|
||||||
FlowSummaryPrivate::Steps::summaryLocalStep(node1, node2.(FlowSummaryNode).getSummaryNode(),
|
FlowSummaryPrivate::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(),
|
||||||
false, _) // TODO: preserve 'model' parameter
|
node2.(FlowSummaryNode).getSummaryNode(), false, _) // TODO: preserve 'model' parameter
|
||||||
or
|
or
|
||||||
// Convert steps out of array elements to plain taint steps
|
// Convert steps out of array elements to plain taint steps
|
||||||
FlowSummaryPrivate::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(),
|
FlowSummaryPrivate::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(),
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ private import DataFlowImplSpecific
|
|||||||
private import codeql.dataflow.DataFlow as SharedDataFlow
|
private import codeql.dataflow.DataFlow as SharedDataFlow
|
||||||
private import codeql.dataflow.TaintTracking as SharedTaintTracking
|
private import codeql.dataflow.TaintTracking as SharedTaintTracking
|
||||||
private import codeql.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
private import codeql.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||||
private import codeql.util.Void
|
|
||||||
|
|
||||||
module JSDataFlow implements SharedDataFlow::InputSig<Location> {
|
module JSDataFlow implements SharedDataFlow::InputSig<Location> {
|
||||||
import Private
|
import Private
|
||||||
@@ -29,8 +28,6 @@ module JSFlowSummary implements FlowSummaryImpl::InputSig<Location, JSDataFlow>
|
|||||||
private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate
|
private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate
|
||||||
import FlowSummaryPrivate
|
import FlowSummaryPrivate
|
||||||
|
|
||||||
class FlowSummaryCallBase = Void;
|
|
||||||
|
|
||||||
overlay[local]
|
overlay[local]
|
||||||
predicate callableFromSource(SummarizedCallableBase c) { none() }
|
predicate callableFromSource(SummarizedCallableBase c) { none() }
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ private module Input implements InputSig<Location, PythonDataFlow> {
|
|||||||
// parameter, but dataflow-consistency queries should _not_ complain about there not
|
// parameter, but dataflow-consistency queries should _not_ complain about there not
|
||||||
// being a post-update node for the synthetic `**kwargs` parameter.
|
// being a post-update node for the synthetic `**kwargs` parameter.
|
||||||
n instanceof SynthDictSplatParameterNode
|
n instanceof SynthDictSplatParameterNode
|
||||||
or
|
|
||||||
Private::Conversions::readStep(n, _, _)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
|
predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ ql/python/ql/src/Metrics/NumberOfStatements.ql
|
|||||||
ql/python/ql/src/Metrics/TransitiveImports.ql
|
ql/python/ql/src/Metrics/TransitiveImports.ql
|
||||||
ql/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.ql
|
ql/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.ql
|
||||||
ql/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql
|
ql/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql
|
||||||
ql/python/ql/src/Security/CWE-1427/UserPromptInjection.ql
|
|
||||||
ql/python/ql/src/Security/CWE-798/HardcodedCredentials.ql
|
ql/python/ql/src/Security/CWE-798/HardcodedCredentials.ql
|
||||||
ql/python/ql/src/Statements/C_StyleParentheses.ql
|
ql/python/ql/src/Statements/C_StyleParentheses.ql
|
||||||
ql/python/ql/src/Statements/DocStrings.ql
|
ql/python/ql/src/Statements/DocStrings.ql
|
||||||
@@ -88,6 +87,7 @@ ql/python/ql/src/experimental/Security/CWE-079/EmailXss.ql
|
|||||||
ql/python/ql/src/experimental/Security/CWE-091/XsltInjection.ql
|
ql/python/ql/src/experimental/Security/CWE-091/XsltInjection.ql
|
||||||
ql/python/ql/src/experimental/Security/CWE-094/Js2Py.ql
|
ql/python/ql/src/experimental/Security/CWE-094/Js2Py.ql
|
||||||
ql/python/ql/src/experimental/Security/CWE-1236/CsvInjection.ql
|
ql/python/ql/src/experimental/Security/CWE-1236/CsvInjection.ql
|
||||||
|
ql/python/ql/src/experimental/Security/CWE-1427/PromptInjection.ql
|
||||||
ql/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidation.ql
|
ql/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidation.ql
|
||||||
ql/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql
|
ql/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql
|
||||||
ql/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql
|
ql/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ ql/python/ql/src/Security/CWE-1004/NonHttpOnlyCookie.ql
|
|||||||
ql/python/ql/src/Security/CWE-113/HeaderInjection.ql
|
ql/python/ql/src/Security/CWE-113/HeaderInjection.ql
|
||||||
ql/python/ql/src/Security/CWE-116/BadTagFilter.ql
|
ql/python/ql/src/Security/CWE-116/BadTagFilter.ql
|
||||||
ql/python/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
|
ql/python/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
|
||||||
ql/python/ql/src/Security/CWE-1427/SystemPromptInjection.ql
|
|
||||||
ql/python/ql/src/Security/CWE-209/StackTraceExposure.ql
|
ql/python/ql/src/Security/CWE-209/StackTraceExposure.ql
|
||||||
ql/python/ql/src/Security/CWE-215/FlaskDebug.ql
|
ql/python/ql/src/Security/CWE-215/FlaskDebug.ql
|
||||||
ql/python/ql/src/Security/CWE-285/PamAuthorization.ql
|
ql/python/ql/src/Security/CWE-285/PamAuthorization.ql
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ ql/python/ql/src/Security/CWE-113/HeaderInjection.ql
|
|||||||
ql/python/ql/src/Security/CWE-116/BadTagFilter.ql
|
ql/python/ql/src/Security/CWE-116/BadTagFilter.ql
|
||||||
ql/python/ql/src/Security/CWE-117/LogInjection.ql
|
ql/python/ql/src/Security/CWE-117/LogInjection.ql
|
||||||
ql/python/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
|
ql/python/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
|
||||||
ql/python/ql/src/Security/CWE-1427/SystemPromptInjection.ql
|
|
||||||
ql/python/ql/src/Security/CWE-209/StackTraceExposure.ql
|
ql/python/ql/src/Security/CWE-209/StackTraceExposure.ql
|
||||||
ql/python/ql/src/Security/CWE-215/FlaskDebug.ql
|
ql/python/ql/src/Security/CWE-215/FlaskDebug.ql
|
||||||
ql/python/ql/src/Security/CWE-285/PamAuthorization.ql
|
ql/python/ql/src/Security/CWE-285/PamAuthorization.ql
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ ql/python/ql/src/Security/CWE-113/HeaderInjection.ql
|
|||||||
ql/python/ql/src/Security/CWE-116/BadTagFilter.ql
|
ql/python/ql/src/Security/CWE-116/BadTagFilter.ql
|
||||||
ql/python/ql/src/Security/CWE-117/LogInjection.ql
|
ql/python/ql/src/Security/CWE-117/LogInjection.ql
|
||||||
ql/python/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
|
ql/python/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
|
||||||
ql/python/ql/src/Security/CWE-1427/SystemPromptInjection.ql
|
|
||||||
ql/python/ql/src/Security/CWE-209/StackTraceExposure.ql
|
ql/python/ql/src/Security/CWE-209/StackTraceExposure.ql
|
||||||
ql/python/ql/src/Security/CWE-215/FlaskDebug.ql
|
ql/python/ql/src/Security/CWE-215/FlaskDebug.ql
|
||||||
ql/python/ql/src/Security/CWE-285/PamAuthorization.ql
|
ql/python/ql/src/Security/CWE-285/PamAuthorization.ql
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
print(0)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
| code/main.py:0:0:0:0 | code/main.py | |
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import python
|
|
||||||
|
|
||||||
from File f, string relative
|
|
||||||
where if exists(f.getRelativePath()) then relative = "relative" else relative = ""
|
|
||||||
select f, relative
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import runs_on
|
|
||||||
|
|
||||||
|
|
||||||
@runs_on.windows
|
|
||||||
def test(codeql, python, cwd, subst_drive):
|
|
||||||
drive = subst_drive(cwd / "code")
|
|
||||||
codeql.database.create(source_root=drive)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
category: minorAnalysis
|
|
||||||
---
|
|
||||||
* Added prompt-injection sink models (`system-prompt-injection` and `user-prompt-injection` kinds) for the `openai`, `agents`, `anthropic`, `google-genai`, `openrouter` and `langchain` frameworks.
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
|
||||||
|
- Temporarily disabled the `instanceFieldStep` disjunct of the internal `TypeTrackingInput::levelStepCall` predicate, which was introduced in 7.2.0 and caused catastrophic query slowdowns on some OOP-heavy Python codebases (e.g. `mypy` and `dask`).
|
||||||
@@ -1794,28 +1794,3 @@ module Cryptography {
|
|||||||
|
|
||||||
import ConceptsShared::Cryptography
|
import ConceptsShared::Cryptography
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A data-flow node that prompts an AI model.
|
|
||||||
*
|
|
||||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
|
||||||
* extend `AIPrompt::Range` instead.
|
|
||||||
*/
|
|
||||||
class AIPrompt extends DataFlow::Node instanceof AIPrompt::Range {
|
|
||||||
/** Gets an input that is used as AI prompt. */
|
|
||||||
DataFlow::Node getAPrompt() { result = super.getAPrompt() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Provides a class for modeling new AI prompting mechanisms. */
|
|
||||||
module AIPrompt {
|
|
||||||
/**
|
|
||||||
* A data-flow node that prompts an AI model.
|
|
||||||
*
|
|
||||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
|
||||||
* extend `AIPrompt` instead.
|
|
||||||
*/
|
|
||||||
abstract class Range extends DataFlow::Node {
|
|
||||||
/** Gets an input that is used as AI prompt. */
|
|
||||||
abstract DataFlow::Node getAPrompt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ predicate simpleLocalFlowStepForTypetracking(Node nodeFrom, Node nodeTo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private predicate summaryLocalStep(Node nodeFrom, Node nodeTo, string model) {
|
private predicate summaryLocalStep(Node nodeFrom, Node nodeTo, string model) {
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,7 +753,7 @@ predicate jumpStepNotSharedWithTypeTracker(Node nodeFrom, Node nodeTo) {
|
|||||||
* As of 2024-04-02 the type-tracking library only supports precise content, so there is
|
* As of 2024-04-02 the type-tracking library only supports precise content, so there is
|
||||||
* no reason to include steps for list content right now.
|
* no reason to include steps for list content right now.
|
||||||
*/
|
*/
|
||||||
predicate storeStepCommon(Node nodeFrom, Content c, Node nodeTo) {
|
predicate storeStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) {
|
||||||
tupleStoreStep(nodeFrom, c, nodeTo)
|
tupleStoreStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
dictStoreStep(nodeFrom, c, nodeTo)
|
dictStoreStep(nodeFrom, c, nodeTo)
|
||||||
@@ -767,8 +767,7 @@ predicate storeStepCommon(Node nodeFrom, Content c, Node nodeTo) {
|
|||||||
* Holds if data can flow from `nodeFrom` to `nodeTo` via an assignment to
|
* Holds if data can flow from `nodeFrom` to `nodeTo` via an assignment to
|
||||||
* content `c`.
|
* content `c`.
|
||||||
*/
|
*/
|
||||||
predicate storeStep(Node nodeFrom, ContentSet cs, Node nodeTo) {
|
predicate storeStep(Node nodeFrom, ContentSet c, Node nodeTo) {
|
||||||
exists(Content c | cs = singleton(c) |
|
|
||||||
storeStepCommon(nodeFrom, c, nodeTo)
|
storeStepCommon(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
listStoreStep(nodeFrom, c, nodeTo)
|
listStoreStep(nodeFrom, c, nodeTo)
|
||||||
@@ -781,6 +780,9 @@ predicate storeStep(Node nodeFrom, ContentSet cs, Node nodeTo) {
|
|||||||
or
|
or
|
||||||
any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo)
|
any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
|
FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c,
|
||||||
|
nodeTo.(FlowSummaryNode).getSummaryNode())
|
||||||
|
or
|
||||||
synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo)
|
synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo)
|
synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo)
|
||||||
@@ -788,10 +790,6 @@ predicate storeStep(Node nodeFrom, ContentSet cs, Node nodeTo) {
|
|||||||
yieldStoreStep(nodeFrom, c, nodeTo)
|
yieldStoreStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
VariableCapture::storeStep(nodeFrom, c, nodeTo)
|
VariableCapture::storeStep(nodeFrom, c, nodeTo)
|
||||||
)
|
|
||||||
or
|
|
||||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), cs,
|
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -987,7 +985,7 @@ predicate attributeStoreStep(Node nodeFrom, AttributeContent c, Node nodeTo) {
|
|||||||
/**
|
/**
|
||||||
* Subset of `readStep` that should be shared with type-tracking.
|
* Subset of `readStep` that should be shared with type-tracking.
|
||||||
*/
|
*/
|
||||||
predicate readStepCommon(Node nodeFrom, Content c, Node nodeTo) {
|
predicate readStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) {
|
||||||
subscriptReadStep(nodeFrom, c, nodeTo)
|
subscriptReadStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
iterableUnpackingReadStep(nodeFrom, c, nodeTo)
|
iterableUnpackingReadStep(nodeFrom, c, nodeTo)
|
||||||
@@ -996,8 +994,7 @@ predicate readStepCommon(Node nodeFrom, Content c, Node nodeTo) {
|
|||||||
/**
|
/**
|
||||||
* Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`.
|
* Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`.
|
||||||
*/
|
*/
|
||||||
predicate readStep(Node nodeFrom, ContentSet cs, Node nodeTo) {
|
predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) {
|
||||||
exists(Content c | cs = singleton(c) |
|
|
||||||
readStepCommon(nodeFrom, c, nodeTo)
|
readStepCommon(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
matchReadStep(nodeFrom, c, nodeTo)
|
matchReadStep(nodeFrom, c, nodeTo)
|
||||||
@@ -1006,15 +1003,12 @@ predicate readStep(Node nodeFrom, ContentSet cs, Node nodeTo) {
|
|||||||
or
|
or
|
||||||
attributeReadStep(nodeFrom, c, nodeTo)
|
attributeReadStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
|
FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c,
|
||||||
|
nodeTo.(FlowSummaryNode).getSummaryNode())
|
||||||
|
or
|
||||||
synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo)
|
synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo)
|
||||||
or
|
or
|
||||||
VariableCapture::readStep(nodeFrom, c, nodeTo)
|
VariableCapture::readStep(nodeFrom, c, nodeTo)
|
||||||
)
|
|
||||||
or
|
|
||||||
FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), cs,
|
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode())
|
|
||||||
or
|
|
||||||
Conversions::readStep(nodeFrom, cs, nodeTo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Data flows from a sequence to a subscript of the sequence. */
|
/** Data flows from a sequence to a subscript of the sequence. */
|
||||||
@@ -1070,77 +1064,30 @@ predicate attributeReadStep(Node nodeFrom, AttributeContent c, AttrRead nodeTo)
|
|||||||
nodeTo.accesses(nodeFrom, c.getAttribute())
|
nodeTo.accesses(nodeFrom, c.getAttribute())
|
||||||
}
|
}
|
||||||
|
|
||||||
module Conversions {
|
|
||||||
private import semmle.python.Concepts
|
|
||||||
|
|
||||||
predicate decoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) {
|
|
||||||
exists(Decoding decoding |
|
|
||||||
nodeFrom = decoding.getAnInput() and
|
|
||||||
nodeTo = decoding.getOutput()
|
|
||||||
) and
|
|
||||||
c.isAnyTupleOrDictionaryElement()
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate encoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) {
|
|
||||||
exists(Encoding encoding |
|
|
||||||
nodeFrom = encoding.getAnInput() and
|
|
||||||
nodeTo = encoding.getOutput()
|
|
||||||
) and
|
|
||||||
c.isAnyTupleOrDictionaryElement()
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate formatReadStep(Node nodeFrom, ContentSet c, Node nodeTo) {
|
|
||||||
// % formatting
|
|
||||||
exists(BinaryExprNode fmt | fmt = nodeTo.asCfgNode() |
|
|
||||||
fmt.getOp() instanceof Mod and
|
|
||||||
fmt.getRight() = nodeFrom.asCfgNode()
|
|
||||||
) and
|
|
||||||
c.isAnyTupleElement()
|
|
||||||
or
|
|
||||||
// format_map
|
|
||||||
// see https://docs.python.org/3/library/stdtypes.html#str.format_map
|
|
||||||
nodeTo.(MethodCallNode).calls(_, "format_map") and
|
|
||||||
nodeTo.(MethodCallNode).getArg(0) = nodeFrom and
|
|
||||||
c.isAnyDictionaryElement()
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) {
|
|
||||||
decoderReadStep(nodeFrom, c, nodeTo)
|
|
||||||
or
|
|
||||||
encoderReadStep(nodeFrom, c, nodeTo)
|
|
||||||
or
|
|
||||||
formatReadStep(nodeFrom, c, nodeTo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if values stored inside content `c` are cleared at node `n`. For example,
|
* Holds if values stored inside content `c` are cleared at node `n`. For example,
|
||||||
* any value stored inside `f` is cleared at the pre-update node associated with `x`
|
* any value stored inside `f` is cleared at the pre-update node associated with `x`
|
||||||
* in `x.f = newValue`.
|
* in `x.f = newValue`.
|
||||||
*/
|
*/
|
||||||
predicate clearsContent(Node n, ContentSet cs) {
|
predicate clearsContent(Node n, ContentSet c) {
|
||||||
exists(Content c | cs = singleton(c) |
|
|
||||||
matchClearStep(n, c)
|
matchClearStep(n, c)
|
||||||
or
|
or
|
||||||
attributeClearStep(n, c)
|
attributeClearStep(n, c)
|
||||||
or
|
or
|
||||||
dictClearStep(n, c)
|
dictClearStep(n, c)
|
||||||
or
|
or
|
||||||
|
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||||
|
or
|
||||||
dictSplatParameterNodeClearStep(n, c)
|
dictSplatParameterNodeClearStep(n, c)
|
||||||
or
|
or
|
||||||
VariableCapture::clearsContent(n, c)
|
VariableCapture::clearsContent(n, c)
|
||||||
)
|
|
||||||
or
|
|
||||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), cs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the value that is being tracked is expected to be stored inside content `c`
|
* Holds if the value that is being tracked is expected to be stored inside content `c`
|
||||||
* at node `n`.
|
* at node `n`.
|
||||||
*/
|
*/
|
||||||
predicate expectsContent(Node n, ContentSet c) {
|
predicate expectsContent(Node n, ContentSet c) { none() }
|
||||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if values stored inside attribute `c` are cleared at node `n`.
|
* Holds if values stored inside attribute `c` are cleared at node `n`.
|
||||||
@@ -1251,65 +1198,12 @@ predicate allowParameterReturnInSelf(ParameterNode p) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
bindingset[s]
|
|
||||||
private string getFirstChar(string s) {
|
|
||||||
result =
|
|
||||||
min(int i, string c |
|
|
||||||
c = s.charAt(i) and c != "_"
|
|
||||||
or
|
|
||||||
c = "" and i = s.length()
|
|
||||||
|
|
|
||||||
c order by i
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private string getAttributeContentFirstChar(AttributeContent ac) {
|
|
||||||
result = getFirstChar(ac.getAttribute())
|
|
||||||
}
|
|
||||||
|
|
||||||
private string getDictionaryElementContentKeyFirstChar(DictionaryElementContent dec) {
|
|
||||||
result = getFirstChar(dec.getKey())
|
|
||||||
}
|
|
||||||
|
|
||||||
private newtype TContentApprox =
|
|
||||||
TListElementContentApprox() or
|
|
||||||
TSetElementContentApprox() or
|
|
||||||
TTupleElementContentApprox() or
|
|
||||||
TDictionaryElementContentApprox(string first) {
|
|
||||||
first = "" // for `TDictionaryElementAnyContent`
|
|
||||||
or
|
|
||||||
first = getDictionaryElementContentKeyFirstChar(_)
|
|
||||||
} or
|
|
||||||
TAttributeContentApprox(string first) { first = getAttributeContentFirstChar(_) } or
|
|
||||||
TCapturedVariableContentApprox()
|
|
||||||
|
|
||||||
/** An approximated `Content`. */
|
/** An approximated `Content`. */
|
||||||
class ContentApprox extends TContentApprox {
|
class ContentApprox = Unit;
|
||||||
/** Gets a textual representation of this element. */
|
|
||||||
string toString() { result = "" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets an approximated value for content `c`. */
|
/** Gets an approximated value for content `c`. */
|
||||||
ContentApprox getContentApprox(Content c) {
|
pragma[inline]
|
||||||
c = TListElementContent() and
|
ContentApprox getContentApprox(Content c) { any() }
|
||||||
result = TListElementContentApprox()
|
|
||||||
or
|
|
||||||
c = TSetElementContent() and
|
|
||||||
result = TSetElementContentApprox()
|
|
||||||
or
|
|
||||||
c = TTupleElementContent(_) and
|
|
||||||
result = TTupleElementContentApprox()
|
|
||||||
or
|
|
||||||
result = TDictionaryElementContentApprox(getDictionaryElementContentKeyFirstChar(c))
|
|
||||||
or
|
|
||||||
c = TDictionaryElementAnyContent() and
|
|
||||||
result = TDictionaryElementContentApprox("")
|
|
||||||
or
|
|
||||||
result = TAttributeContentApprox(getAttributeContentFirstChar(c))
|
|
||||||
or
|
|
||||||
c = TCapturedVariableContent(_) and
|
|
||||||
result = TCapturedVariableContentApprox()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper for `.getEnclosingCallable`. */
|
/** Helper for `.getEnclosingCallable`. */
|
||||||
DataFlowCallable getCallableScope(Scope s) {
|
DataFlowCallable getCallableScope(Scope s) {
|
||||||
|
|||||||
@@ -898,78 +898,19 @@ class CapturedVariableContent extends Content, TCapturedVariableContent {
|
|||||||
override string getMaDRepresentation() { none() }
|
override string getMaDRepresentation() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* An entity that represents a set of `Content`s.
|
|
||||||
*
|
|
||||||
* Most `ContentSet`s are singletons (i.e. they consist of a single `Content`),
|
|
||||||
* but `AnyDictionaryElement` and `AnyTupleElement` act as wildcards on the
|
|
||||||
* read side: a read at such a `ContentSet` matches any specific dictionary
|
|
||||||
* key / tuple index store, as well as (for dictionaries) the
|
|
||||||
* "unknown-bucket" Content `DictionaryElementAnyContent`.
|
|
||||||
*
|
|
||||||
* Keeping these as wildcard `ContentSet`s (rather than enumerating one
|
|
||||||
* `ContentSet` per key/index) keeps the dataflow `readSetEx` relation small
|
|
||||||
* when implicit reads are used (e.g. at sinks via `defaultImplicitTaintRead`).
|
|
||||||
*/
|
|
||||||
private newtype TContentSet =
|
|
||||||
TSingletonContent(Content c) or
|
|
||||||
TAnyTupleElement() or
|
|
||||||
TAnyDictionaryElement() or
|
|
||||||
TAnyTupleOrDictionaryElement()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entity that represents a set of `Content`s.
|
* An entity that represents a set of `Content`s.
|
||||||
*
|
*
|
||||||
* The set may be interpreted differently depending on whether it is
|
* The set may be interpreted differently depending on whether it is
|
||||||
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
||||||
*/
|
*/
|
||||||
class ContentSet extends TContentSet {
|
class ContentSet instanceof Content {
|
||||||
/** Holds if this content set is the singleton `{c}`. */
|
|
||||||
predicate isSingleton(Content c) { this = TSingletonContent(c) }
|
|
||||||
|
|
||||||
/** Holds if this content set is the wildcard for all tuple elements. */
|
|
||||||
predicate isAnyTupleElement() { this = TAnyTupleElement() }
|
|
||||||
|
|
||||||
/** Holds if this content set is the wildcard for all dictionary elements. */
|
|
||||||
predicate isAnyDictionaryElement() { this = TAnyDictionaryElement() }
|
|
||||||
|
|
||||||
/** Holds if this content set is the wildcard for all tuple elements or dictionary elements. */
|
|
||||||
predicate isAnyTupleOrDictionaryElement() { this = TAnyTupleOrDictionaryElement() }
|
|
||||||
|
|
||||||
/** Gets a content that may be stored into when storing into this set. */
|
/** Gets a content that may be stored into when storing into this set. */
|
||||||
Content getAStoreContent() { this = TSingletonContent(result) }
|
Content getAStoreContent() { result = this }
|
||||||
|
|
||||||
/** Gets a content that may be read from when reading from this set. */
|
/** Gets a content that may be read from when reading from this set. */
|
||||||
Content getAReadContent() {
|
Content getAReadContent() { result = this }
|
||||||
this = TSingletonContent(result)
|
|
||||||
or
|
|
||||||
// Wildcard expansion: a read at "any tuple element" matches a store at any
|
|
||||||
// specific tuple index. (Stores always target a specific index, so we don't
|
|
||||||
// need a `TupleElementAnyContent` Content kind here.)
|
|
||||||
this = TAnyTupleElement() and result instanceof TupleElementContent
|
|
||||||
or
|
|
||||||
this = TAnyDictionaryElement() and
|
|
||||||
(result instanceof DictionaryElementContent or result instanceof DictionaryElementAnyContent)
|
|
||||||
or
|
|
||||||
this = TAnyTupleOrDictionaryElement() and
|
|
||||||
(
|
|
||||||
result instanceof TupleElementContent or
|
|
||||||
result instanceof DictionaryElementContent or
|
|
||||||
result instanceof DictionaryElementAnyContent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a textual representation of this content set. */
|
/** Gets a textual representation of this content set. */
|
||||||
string toString() {
|
string toString() { result = super.toString() }
|
||||||
exists(Content c | this = TSingletonContent(c) | result = c.toString())
|
|
||||||
or
|
|
||||||
this = TAnyTupleElement() and result = "Any tuple element"
|
|
||||||
or
|
|
||||||
this = TAnyDictionaryElement() and result = "Any dictionary element"
|
|
||||||
or
|
|
||||||
this = TAnyTupleOrDictionaryElement() and result = "Any tuple or dictionary element"
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the singleton `ContentSet` wrapping the `Content` `c`. */
|
|
||||||
ContentSet singleton(Content c) { result = TSingletonContent(c) }
|
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow>
|
|||||||
|
|
||||||
class SinkBase = Void;
|
class SinkBase = Void;
|
||||||
|
|
||||||
class FlowSummaryCallBase = Void;
|
|
||||||
|
|
||||||
predicate callableFromSource(SummarizedCallableBase c) { none() }
|
predicate callableFromSource(SummarizedCallableBase c) { none() }
|
||||||
|
|
||||||
ArgumentPosition callbackSelfParameterPosition() { result.isLambdaSelf() }
|
ArgumentPosition callbackSelfParameterPosition() { result.isLambdaSelf() }
|
||||||
@@ -68,33 +66,23 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow>
|
|||||||
}
|
}
|
||||||
|
|
||||||
string encodeContent(ContentSet cs, string arg) {
|
string encodeContent(ContentSet cs, string arg) {
|
||||||
exists(Content c | cs.isSingleton(c) |
|
cs = TListElementContent() and result = "ListElement" and arg = ""
|
||||||
c = TListElementContent() and result = "ListElement" and arg = ""
|
|
||||||
or
|
or
|
||||||
c = TSetElementContent() and result = "SetElement" and arg = ""
|
cs = TSetElementContent() and result = "SetElement" and arg = ""
|
||||||
or
|
or
|
||||||
exists(int index |
|
exists(int index |
|
||||||
c = TTupleElementContent(index) and result = "TupleElement" and arg = index.toString()
|
cs = TTupleElementContent(index) and result = "TupleElement" and arg = index.toString()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string key |
|
exists(string key |
|
||||||
c = TDictionaryElementContent(key) and result = "DictionaryElement" and arg = key
|
cs = TDictionaryElementContent(key) and result = "DictionaryElement" and arg = key
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
c = TDictionaryElementAnyContent() and result = "DictionaryElementAny" and arg = ""
|
cs = TDictionaryElementAnyContent() and result = "DictionaryElementAny" and arg = ""
|
||||||
or
|
or
|
||||||
exists(string attr | c = TAttributeContent(attr) and result = "Attribute" and arg = attr)
|
exists(string attr | cs = TAttributeContent(attr) and result = "Attribute" and arg = attr)
|
||||||
)
|
|
||||||
or
|
|
||||||
cs.isAnyTupleElement() and result = "AnyTupleElement" and arg = ""
|
|
||||||
or
|
|
||||||
cs.isAnyDictionaryElement() and result = "AnyDictionaryElement" and arg = ""
|
|
||||||
or
|
|
||||||
cs.isAnyTupleOrDictionaryElement() and result = "AnyTupleOrDictionaryElement" and arg = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) }
|
|
||||||
|
|
||||||
bindingset[token]
|
bindingset[token]
|
||||||
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
|
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
|
||||||
// needed to support `Argument[x..y]` ranges
|
// needed to support `Argument[x..y]` ranges
|
||||||
@@ -113,10 +101,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow>
|
|||||||
private import Make<Location, DataFlowImplSpecific::PythonDataFlow, Input> as Impl
|
private import Make<Location, DataFlowImplSpecific::PythonDataFlow, Input> as Impl
|
||||||
|
|
||||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||||
Impl::Private::SummaryNode getSummaryNode(Node n) {
|
|
||||||
result = n.(FlowSummaryNode).getSummaryNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay[global]
|
overlay[global]
|
||||||
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
||||||
result =
|
result =
|
||||||
@@ -155,29 +139,27 @@ module Private {
|
|||||||
predicate withContent = SC::withContent/1;
|
predicate withContent = SC::withContent/1;
|
||||||
|
|
||||||
/** Gets a summary component that represents a list element. */
|
/** Gets a summary component that represents a list element. */
|
||||||
SummaryComponent listElement() { result = content(singleton(any(ListElementContent c))) }
|
SummaryComponent listElement() { result = content(any(ListElementContent c)) }
|
||||||
|
|
||||||
/** Gets a summary component that represents a set element. */
|
/** Gets a summary component that represents a set element. */
|
||||||
SummaryComponent setElement() { result = content(singleton(any(SetElementContent c))) }
|
SummaryComponent setElement() { result = content(any(SetElementContent c)) }
|
||||||
|
|
||||||
/** Gets a summary component that represents a tuple element. */
|
/** Gets a summary component that represents a tuple element. */
|
||||||
SummaryComponent tupleElement(int index) {
|
SummaryComponent tupleElement(int index) {
|
||||||
exists(TupleElementContent c | c.getIndex() = index and result = content(singleton(c)))
|
exists(TupleElementContent c | c.getIndex() = index and result = content(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a summary component that represents a dictionary element. */
|
/** Gets a summary component that represents a dictionary element. */
|
||||||
SummaryComponent dictionaryElement(string key) {
|
SummaryComponent dictionaryElement(string key) {
|
||||||
exists(DictionaryElementContent c | c.getKey() = key and result = content(singleton(c)))
|
exists(DictionaryElementContent c | c.getKey() = key and result = content(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a summary component that represents a dictionary element at any key. */
|
/** Gets a summary component that represents a dictionary element at any key. */
|
||||||
SummaryComponent dictionaryElementAny() {
|
SummaryComponent dictionaryElementAny() { result = content(any(DictionaryElementAnyContent c)) }
|
||||||
result = content(singleton(any(DictionaryElementAnyContent c)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a summary component that represents an attribute element. */
|
/** Gets a summary component that represents an attribute element. */
|
||||||
SummaryComponent attribute(string attr) {
|
SummaryComponent attribute(string attr) {
|
||||||
exists(AttributeContent c | c.getAttribute() = attr and result = content(singleton(c)))
|
exists(AttributeContent c | c.getAttribute() = attr and result = content(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a summary component that represents the return value of a call. */
|
/** Gets a summary component that represents the return value of a call. */
|
||||||
|
|||||||
@@ -11,34 +11,12 @@ private import semmle.python.ApiGraphs
|
|||||||
*/
|
*/
|
||||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if default taint tracking should read content `contentSet` implicitly and
|
|
||||||
* propagate taint from a container to reads of that content.
|
|
||||||
*/
|
|
||||||
private predicate defaultTaintReadContent(DataFlow::ContentSet contentSet) {
|
|
||||||
// Tuple and dictionary content is precise, so use wildcard content sets to avoid
|
|
||||||
// blowing up the size of `Stage1::readSetEx` (otherwise this predicate would
|
|
||||||
// expand to one row per (node, distinct key or index) and the framework's
|
|
||||||
// read-set relation grows quadratically). `ContentSet.getAReadContent` expands
|
|
||||||
// these wildcards back to the specific contents when matching against stores.
|
|
||||||
contentSet.isAnyTupleOrDictionaryElement()
|
|
||||||
or
|
|
||||||
// List and set element content is already imprecise, so no wildcard expansion is
|
|
||||||
// needed.
|
|
||||||
contentSet.getAStoreContent() instanceof DataFlow::ListElementContent
|
|
||||||
or
|
|
||||||
contentSet.getAStoreContent() instanceof DataFlow::SetElementContent
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
|
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
|
||||||
* of `c` at sinks and inputs to additional taint steps.
|
* of `c` at sinks and inputs to additional taint steps.
|
||||||
*/
|
*/
|
||||||
bindingset[node]
|
bindingset[node]
|
||||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||||
exists(node) and
|
|
||||||
defaultTaintReadContent(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
private module Cached {
|
private module Cached {
|
||||||
/**
|
/**
|
||||||
@@ -80,8 +58,10 @@ private module Cached {
|
|||||||
) and
|
) and
|
||||||
model = ""
|
model = ""
|
||||||
or
|
or
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom
|
||||||
nodeTo.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model)
|
.(DataFlowPrivate::FlowSummaryNode)
|
||||||
|
.getSummaryNode(), nodeTo.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false,
|
||||||
|
model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +128,11 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT
|
|||||||
nodeFrom.getNode() = object and
|
nodeFrom.getNode() = object and
|
||||||
method_name in ["partition", "rpartition", "rsplit", "split", "splitlines"]
|
method_name in ["partition", "rpartition", "rsplit", "split", "splitlines"]
|
||||||
or
|
or
|
||||||
|
// Iterable[str] -> str
|
||||||
|
// TODO: check if these should be handled differently in regards to content
|
||||||
|
method_name = "join" and
|
||||||
|
nodeFrom.getNode() = call.getArg(0)
|
||||||
|
or
|
||||||
// Mapping[str, Any] -> str
|
// Mapping[str, Any] -> str
|
||||||
method_name = "format_map" and
|
method_name = "format_map" and
|
||||||
nodeFrom.getNode() = call.getArg(0)
|
nodeFrom.getNode() = call.getArg(0)
|
||||||
@@ -176,21 +161,32 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to reading
|
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to containers
|
||||||
* content from containers (lists/sets/dictionaries/tuples): subscripts, iteration,
|
* (lists/sets/dictionaries): literals, constructor invocation, methods. Note that this
|
||||||
* constructor invocation, methods.
|
* is currently very imprecise, as an example, since we model `dict.get`, we treat any
|
||||||
|
* `<tainted object>.get(<arg>)` will be tainted, whether it's true or not.
|
||||||
*/
|
*/
|
||||||
predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||||
exists(DataFlow::ContentSet contentSet |
|
// construction by literal
|
||||||
DataFlowPrivate::readStep(nodeFrom, contentSet, nodeTo) and
|
//
|
||||||
exists(DataFlow::Content c | c = contentSet.getAReadContent() |
|
// TODO: once we have proper flow-summary modeling, we might not need this step any
|
||||||
c instanceof DataFlow::TupleElementContent or
|
// longer -- but there needs to be a matching read-step for the store-step, and we
|
||||||
c instanceof DataFlow::DictionaryElementContent or
|
// don't provide that right now.
|
||||||
c instanceof DataFlow::DictionaryElementAnyContent or
|
DataFlowPrivate::listStoreStep(nodeFrom, _, nodeTo)
|
||||||
c instanceof DataFlow::ListElementContent or
|
or
|
||||||
c instanceof DataFlow::SetElementContent
|
DataFlowPrivate::setStoreStep(nodeFrom, _, nodeTo)
|
||||||
)
|
or
|
||||||
)
|
DataFlowPrivate::tupleStoreStep(nodeFrom, _, nodeTo)
|
||||||
|
or
|
||||||
|
DataFlowPrivate::dictStoreStep(nodeFrom, _, nodeTo)
|
||||||
|
or
|
||||||
|
// comprehension, so there is taint-flow from `x` in `[x for x in xs]` to the
|
||||||
|
// resulting list of the list-comprehension.
|
||||||
|
//
|
||||||
|
// TODO: once we have proper flow-summary modeling, we might not need this step any
|
||||||
|
// longer -- but there needs to be a matching read-step for the store-step, and we
|
||||||
|
// don't provide that right now.
|
||||||
|
DataFlowPrivate::yieldStoreStep(nodeFrom, _, nodeTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ module TypeTrackingInput implements Shared::TypeTrackingInput<Location> {
|
|||||||
// is only fed set/list content)
|
// is only fed set/list content)
|
||||||
not nodeFrom instanceof DataFlowPublic::IterableElementNode
|
not nodeFrom instanceof DataFlowPublic::IterableElementNode
|
||||||
or
|
or
|
||||||
TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, DataFlowPublic::singleton(content))
|
TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,15 +286,14 @@ module TypeTrackingInput implements Shared::TypeTrackingInput<Location> {
|
|||||||
nodeFrom.asCfgNode() instanceof SequenceNode
|
nodeFrom.asCfgNode() instanceof SequenceNode
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, DataFlowPublic::singleton(content))
|
TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`.
|
* Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`.
|
||||||
*/
|
*/
|
||||||
predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content loadContent, Content storeContent) {
|
predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content loadContent, Content storeContent) {
|
||||||
TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo,
|
TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent)
|
||||||
DataFlowPublic::singleton(loadContent), DataFlowPublic::singleton(storeContent))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides classes modeling security-relevant aspects of the `anthropic` package.
|
|
||||||
* See https://github.com/anthropics/anthropic-sdk-python.
|
|
||||||
*
|
|
||||||
* Structurally typed sinks (the `system` field) are modeled via Models as Data:
|
|
||||||
* python/ql/lib/semmle/python/frameworks/anthropic.model.yml
|
|
||||||
*
|
|
||||||
* This file retains only role-filtered message sinks that require inspecting a
|
|
||||||
* sibling `role` key, which MaD cannot express.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import python
|
|
||||||
private import semmle.python.ApiGraphs
|
|
||||||
|
|
||||||
/** Provides classes modeling prompt-injection sinks of the `anthropic` package. */
|
|
||||||
module Anthropic {
|
|
||||||
/** Gets a reference to an `anthropic.Anthropic` client instance. */
|
|
||||||
private API::Node classRef() {
|
|
||||||
result = API::moduleImport("anthropic").getMember(["Anthropic", "AsyncAnthropic"]).getReturn()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the message dictionaries passed to `messages.create`/`messages.stream` (stable and beta). */
|
|
||||||
private API::Node messageElement() {
|
|
||||||
exists(API::Node create |
|
|
||||||
create = classRef().getMember("messages").getMember(["create", "stream"])
|
|
||||||
or
|
|
||||||
create = classRef().getMember("beta").getMember("messages").getMember(["create", "stream"])
|
|
||||||
|
|
|
||||||
result = create.getKeywordParameter("messages").getASubscript()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered system/assistant message content sinks that MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getSystemOrAssistantPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = messageElement() and
|
|
||||||
msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
["system", "assistant"]
|
|
||||||
|
|
|
||||||
result = msg.getSubscript("content")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered user message content sinks that MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getUserPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = messageElement() and
|
|
||||||
not msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
["system", "assistant"]
|
|
||||||
|
|
|
||||||
result = msg.getSubscript("content")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides classes modeling security-relevant aspects of the `google-genai` package.
|
|
||||||
* See https://github.com/googleapis/python-genai.
|
|
||||||
*
|
|
||||||
* Structurally typed sinks (`system_instruction`, `contents`, etc.) are modeled via
|
|
||||||
* Models as Data: python/ql/lib/semmle/python/frameworks/google-genai.model.yml
|
|
||||||
*
|
|
||||||
* This file retains only role-filtered content sinks that require inspecting a
|
|
||||||
* sibling `role` key, which MaD cannot express.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import python
|
|
||||||
private import semmle.python.ApiGraphs
|
|
||||||
|
|
||||||
/** Provides classes modeling prompt-injection sinks of the `google-genai` package. */
|
|
||||||
module GoogleGenAI {
|
|
||||||
/** Gets a reference to a `google.genai.Client` instance. */
|
|
||||||
private API::Node clientRef() {
|
|
||||||
result = API::moduleImport("google").getMember("genai").getMember("Client").getReturn()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the content dictionaries passed to `models.generate_content`/`generate_content_stream`. */
|
|
||||||
private API::Node contentElement() {
|
|
||||||
result =
|
|
||||||
clientRef()
|
|
||||||
.getMember("models")
|
|
||||||
.getMember(["generate_content", "generate_content_stream"])
|
|
||||||
.getKeywordParameter("contents")
|
|
||||||
.getASubscript()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered system/model content sinks that MaD cannot express.
|
|
||||||
* Gemini uses the "model" role instead of "assistant".
|
|
||||||
*/
|
|
||||||
API::Node getSystemOrAssistantPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = contentElement() and
|
|
||||||
msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
["system", "model"]
|
|
||||||
|
|
|
||||||
result = msg.getSubscript("parts").getASubscript().getSubscript("text")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered user content sinks that MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getUserPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = contentElement() and
|
|
||||||
not msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
["system", "model"]
|
|
||||||
|
|
|
||||||
result = msg.getSubscript("parts").getASubscript().getSubscript("text")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides classes modeling security-relevant aspects of the `openai` Agents SDK package.
|
|
||||||
* See https://github.com/openai/openai-agents-python.
|
|
||||||
* As well as the regular openai python interface.
|
|
||||||
* See https://github.com/openai/openai-python.
|
|
||||||
*
|
|
||||||
* Structurally typed sinks (instructions, prompt, input, etc.) are modeled via
|
|
||||||
* Models as Data: python/ql/lib/semmle/python/frameworks/openai.model.yml and
|
|
||||||
* python/ql/lib/semmle/python/frameworks/agent.model.yml
|
|
||||||
*
|
|
||||||
* This file retains only role-filtered message sinks that require inspecting a
|
|
||||||
* sibling `role` key, which MaD cannot express.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import python
|
|
||||||
private import semmle.python.ApiGraphs
|
|
||||||
|
|
||||||
/** Holds if `msg` is a message dictionary with a privileged (system/developer/assistant) role. */
|
|
||||||
private predicate isSystemOrDevMessage(API::Node msg) {
|
|
||||||
msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
["system", "developer", "assistant"]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides models for the agents SDK (instances of the `agents.Runner` class etc).
|
|
||||||
*
|
|
||||||
* See https://github.com/openai/openai-agents-python.
|
|
||||||
*/
|
|
||||||
module AgentSdk {
|
|
||||||
/** Gets a reference to the `agents.Runner` class. */
|
|
||||||
API::Node classRef() { result = API::moduleImport("agents").getMember("Runner") }
|
|
||||||
|
|
||||||
/** Gets a reference to the `run` members. */
|
|
||||||
API::Node runMembers() { result = classRef().getMember(["run", "run_sync", "run_streamed"]) }
|
|
||||||
|
|
||||||
/** Gets a reference to the `input` argument of a `Runner.run` call. */
|
|
||||||
private API::Node runInput() {
|
|
||||||
result = runMembers().getKeywordParameter("input")
|
|
||||||
or
|
|
||||||
result = runMembers().getParameter(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered system/developer/assistant message content sinks that
|
|
||||||
* MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getSystemOrAssistantPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = runInput().getASubscript() and
|
|
||||||
isSystemOrDevMessage(msg)
|
|
||||||
|
|
|
||||||
result = msg.getSubscript("content")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered user message content sinks that MaD cannot express.
|
|
||||||
* The string-input case is handled via MaD (agent.model.yml).
|
|
||||||
*/
|
|
||||||
API::Node getUserPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = runInput().getASubscript() and
|
|
||||||
not isSystemOrDevMessage(msg)
|
|
||||||
|
|
|
||||||
result = msg.getSubscript("content")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides models for the OpenAI client (instances of the `openai.OpenAI` class).
|
|
||||||
*
|
|
||||||
* See https://github.com/openai/openai-python.
|
|
||||||
*/
|
|
||||||
module OpenAI {
|
|
||||||
/** Gets a reference to an `openai.OpenAI` client instance. */
|
|
||||||
API::Node classRef() {
|
|
||||||
result =
|
|
||||||
API::moduleImport("openai").getMember(["OpenAI", "AsyncOpenAI", "AzureOpenAI"]).getReturn()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the message dictionaries passed to `chat.completions.create`. */
|
|
||||||
private API::Node chatMessage() {
|
|
||||||
result =
|
|
||||||
classRef()
|
|
||||||
.getMember("chat")
|
|
||||||
.getMember("completions")
|
|
||||||
.getMember("create")
|
|
||||||
.getKeywordParameter("messages")
|
|
||||||
.getASubscript()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the message dictionaries passed as a list to `responses.create`. */
|
|
||||||
private API::Node responsesMessage() {
|
|
||||||
result =
|
|
||||||
classRef()
|
|
||||||
.getMember("responses")
|
|
||||||
.getMember("create")
|
|
||||||
.getKeywordParameter("input")
|
|
||||||
.getASubscript()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the content sink of a message dictionary, including the `text` of structured content. */
|
|
||||||
private API::Node messageContent(API::Node msg) {
|
|
||||||
result = msg.getSubscript("content")
|
|
||||||
or
|
|
||||||
result = msg.getSubscript("content").getASubscript().getSubscript("text")
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the `beta.threads.messages.create` call (Assistants API thread messages). */
|
|
||||||
private API::Node threadMessageCreate() {
|
|
||||||
result =
|
|
||||||
classRef().getMember("beta").getMember("threads").getMember("messages").getMember("create")
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if the `role` keyword of thread-message `call` is a privileged (assistant) role. */
|
|
||||||
private predicate threadRoleIsAssistant(API::Node call) {
|
|
||||||
call.getKeywordParameter("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
"assistant"
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered system/developer/assistant message content sinks that
|
|
||||||
* MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getSystemOrAssistantPromptNode() {
|
|
||||||
exists(API::Node msg | msg = [chatMessage(), responsesMessage()] and isSystemOrDevMessage(msg) |
|
|
||||||
result = messageContent(msg)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(API::Node call | call = threadMessageCreate() and threadRoleIsAssistant(call) |
|
|
||||||
result = call.getKeywordParameter("content")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered user message content sinks that MaD cannot express.
|
|
||||||
* The string-input case is handled via MaD (openai.model.yml).
|
|
||||||
*/
|
|
||||||
API::Node getUserPromptNode() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg = [chatMessage(), responsesMessage()] and not isSystemOrDevMessage(msg)
|
|
||||||
|
|
|
||||||
result = messageContent(msg)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(API::Node call | call = threadMessageCreate() and not threadRoleIsAssistant(call) |
|
|
||||||
result = call.getKeywordParameter("content")
|
|
||||||
)
|
|
||||||
or
|
|
||||||
// realtime conversation items, role cannot be statically resolved in general
|
|
||||||
result =
|
|
||||||
classRef()
|
|
||||||
.getMember("realtime")
|
|
||||||
.getMember("connect")
|
|
||||||
.getReturn()
|
|
||||||
.getMember("conversation")
|
|
||||||
.getMember("item")
|
|
||||||
.getMember("create")
|
|
||||||
.getKeywordParameter("item")
|
|
||||||
.getSubscript("content")
|
|
||||||
.getASubscript()
|
|
||||||
.getSubscript("text")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides classes modeling security-relevant aspects of the OpenRouter Python SDK.
|
|
||||||
* See https://openrouter.ai/docs.
|
|
||||||
*
|
|
||||||
* This file retains only role-filtered message sinks that require inspecting a
|
|
||||||
* sibling `role` key, which MaD cannot express.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import python
|
|
||||||
private import semmle.python.ApiGraphs
|
|
||||||
|
|
||||||
/** Holds if `msg` is a message dictionary with a privileged (system/developer/assistant) role. */
|
|
||||||
private predicate isSystemOrDevMessage(API::Node msg) {
|
|
||||||
msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() =
|
|
||||||
["system", "developer", "assistant"]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Provides classes modeling prompt-injection sinks of the `openrouter` package. */
|
|
||||||
module OpenRouter {
|
|
||||||
/** Gets a reference to an `openrouter.OpenRouter` client instance. */
|
|
||||||
private API::Node clientRef() {
|
|
||||||
result = API::moduleImport("openrouter").getMember("OpenRouter").getReturn()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the message dictionaries passed to `chat.send`. */
|
|
||||||
private API::Node chatMessage() {
|
|
||||||
result =
|
|
||||||
clientRef()
|
|
||||||
.getMember("chat")
|
|
||||||
.getMember("send")
|
|
||||||
.getKeywordParameter("messages")
|
|
||||||
.getASubscript()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the content sink of a message dictionary, including the `text` of structured content. */
|
|
||||||
private API::Node messageContent(API::Node msg) {
|
|
||||||
result = msg.getSubscript("content")
|
|
||||||
or
|
|
||||||
result = msg.getSubscript("content").getASubscript().getSubscript("text")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered system/developer/assistant message content sinks that
|
|
||||||
* MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getSystemOrAssistantPromptNode() {
|
|
||||||
exists(API::Node msg | msg = chatMessage() and isSystemOrDevMessage(msg) |
|
|
||||||
result = messageContent(msg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets role-filtered user message content sinks that MaD cannot express.
|
|
||||||
*/
|
|
||||||
API::Node getUserPromptNode() {
|
|
||||||
exists(API::Node msg | msg = chatMessage() and not isSystemOrDevMessage(msg) |
|
|
||||||
result = messageContent(msg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4199,9 +4199,11 @@ module StdlibPrivate {
|
|||||||
// The positional argument contains a mapping.
|
// The positional argument contains a mapping.
|
||||||
// TODO: these values can be overwritten by keyword arguments
|
// TODO: these values can be overwritten by keyword arguments
|
||||||
// - dict mapping
|
// - dict mapping
|
||||||
input = "Argument[0].WithAnyDictionaryElement" and
|
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
|
||||||
output = "ReturnValue" and
|
input = "Argument[0].DictionaryElement[" + key + "]" and
|
||||||
|
output = "ReturnValue.DictionaryElement[" + key + "]" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// - list-of-pairs mapping
|
// - list-of-pairs mapping
|
||||||
input = "Argument[0].ListElement.TupleElement[1]" and
|
input = "Argument[0].ListElement.TupleElement[1]" and
|
||||||
@@ -4238,10 +4240,11 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[0].SetElement"
|
input = "Argument[0].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[0].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[0].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
// Element content is mutated into list element content
|
|
||||||
output = "ReturnValue.ListElement" and
|
output = "ReturnValue.ListElement" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
or
|
or
|
||||||
@@ -4262,13 +4265,17 @@ module StdlibPrivate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||||
input = "Argument[0].WithAnyTupleElement" and
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
output = "ReturnValue" and
|
input = "Argument[0].TupleElement[" + i.toString() + "]" and
|
||||||
|
output = "ReturnValue.TupleElement[" + i.toString() + "]" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
|
)
|
||||||
or
|
or
|
||||||
input = "Argument[0].ListElement" and
|
// TODO: We need to also translate iterable content such as list element
|
||||||
|
// but we currently lack TupleElementAny
|
||||||
|
input = "Argument[0]" and
|
||||||
output = "ReturnValue" and
|
output = "ReturnValue" and
|
||||||
preservesValue = true
|
preservesValue = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4288,7 +4295,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[0].SetElement"
|
input = "Argument[0].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[0].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[0].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "ReturnValue.SetElement" and
|
output = "ReturnValue.SetElement" and
|
||||||
@@ -4334,7 +4343,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[0].SetElement"
|
input = "Argument[0].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[0].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[0].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "ReturnValue.ListElement" and
|
output = "ReturnValue.ListElement" and
|
||||||
@@ -4362,7 +4373,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
content = "SetElement"
|
content = "SetElement"
|
||||||
or
|
or
|
||||||
content = "AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
content = "TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
|
|
|
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
input = "Argument[0]." + content and
|
input = "Argument[0]." + content and
|
||||||
@@ -4392,7 +4405,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[0].SetElement"
|
input = "Argument[0].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[0].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[0].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "ReturnValue.ListElement" and
|
output = "ReturnValue.ListElement" and
|
||||||
@@ -4420,7 +4435,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[0].SetElement"
|
input = "Argument[0].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[0].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[0].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "ReturnValue" and
|
output = "ReturnValue" and
|
||||||
@@ -4452,7 +4469,9 @@ module StdlibPrivate {
|
|||||||
// We reduce generality slightly by not tracking tuple contents on list arguments beyond the first, for performance.
|
// We reduce generality slightly by not tracking tuple contents on list arguments beyond the first, for performance.
|
||||||
// TODO: Once we have TupleElementAny, this generality can be increased.
|
// TODO: Once we have TupleElementAny, this generality can be increased.
|
||||||
i = 0 and
|
i = 0 and
|
||||||
input = "Argument[1].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int j | j = tc.getIndex() |
|
||||||
|
input = "Argument[1].TupleElement[" + j.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "Argument[0].Parameter[" + i.toString() + "]" and
|
output = "Argument[0].Parameter[" + i.toString() + "]" and
|
||||||
@@ -4481,7 +4500,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[1].SetElement"
|
input = "Argument[1].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[1].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[1].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
(output = "Argument[0].Parameter[0]" or output = "ReturnValue.ListElement") and
|
(output = "Argument[0].Parameter[0]" or output = "ReturnValue.ListElement") and
|
||||||
@@ -4505,7 +4526,9 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[0].SetElement"
|
input = "Argument[0].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[0].AnyTupleElement"
|
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
|
||||||
|
input = "Argument[0].TupleElement[" + i.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "ReturnValue.ListElement.TupleElement[1]" and
|
output = "ReturnValue.ListElement.TupleElement[1]" and
|
||||||
@@ -4530,7 +4553,12 @@ module StdlibPrivate {
|
|||||||
or
|
or
|
||||||
input = "Argument[" + i.toString() + "].SetElement"
|
input = "Argument[" + i.toString() + "].SetElement"
|
||||||
or
|
or
|
||||||
input = "Argument[" + i.toString() + "].AnyTupleElement"
|
// We reduce generality slightly by not tracking tuple contents on arguments beyond the first two, for performance.
|
||||||
|
// TODO: Once we have TupleElementAny, this generality can be increased.
|
||||||
|
i in [0 .. 1] and
|
||||||
|
exists(DataFlow::TupleElementContent tc, int j | j = tc.getIndex() |
|
||||||
|
input = "Argument[" + i.toString() + "].TupleElement[" + j.toString() + "]"
|
||||||
|
)
|
||||||
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
|
||||||
) and
|
) and
|
||||||
output = "ReturnValue.ListElement.TupleElement[" + i.toString() + "]" and
|
output = "ReturnValue.ListElement.TupleElement[" + i.toString() + "]" and
|
||||||
@@ -4553,6 +4581,12 @@ module StdlibPrivate {
|
|||||||
override DataFlow::ArgumentNode getACallback() { none() }
|
override DataFlow::ArgumentNode getACallback() { none() }
|
||||||
|
|
||||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||||
|
exists(DataFlow::Content c |
|
||||||
|
input = "Argument[self]." + c.getMaDRepresentation() and
|
||||||
|
output = "ReturnValue." + c.getMaDRepresentation() and
|
||||||
|
preservesValue = true
|
||||||
|
)
|
||||||
|
or
|
||||||
input = "Argument[self]" and
|
input = "Argument[self]" and
|
||||||
output = "ReturnValue" and
|
output = "ReturnValue" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
@@ -4708,10 +4742,12 @@ module StdlibPrivate {
|
|||||||
override DataFlow::ArgumentNode getACallback() { none() }
|
override DataFlow::ArgumentNode getACallback() { none() }
|
||||||
|
|
||||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||||
input = "Argument[self].AnyDictionaryElement" and
|
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
|
||||||
|
input = "Argument[self].DictionaryElement[" + key + "]" and
|
||||||
output = "ReturnValue.TupleElement[1]" and
|
output = "ReturnValue.TupleElement[1]" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
// TODO: put `key` into "ReturnValue.TupleElement[0]"
|
// TODO: put `key` into "ReturnValue.TupleElement[0]"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4790,9 +4826,11 @@ module StdlibPrivate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||||
input = "Argument[self].AnyDictionaryElement" and
|
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
|
||||||
|
input = "Argument[self].DictionaryElement[" + key + "]" and
|
||||||
output = "ReturnValue.ListElement" and
|
output = "ReturnValue.ListElement" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
|
)
|
||||||
or
|
or
|
||||||
input = "Argument[self]" and
|
input = "Argument[self]" and
|
||||||
output = "ReturnValue" and
|
output = "ReturnValue" and
|
||||||
@@ -4839,9 +4877,11 @@ module StdlibPrivate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||||
input = "Argument[self].AnyDictionaryElement" and
|
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
|
||||||
|
input = "Argument[self].DictionaryElement[" + key + "]" and
|
||||||
output = "ReturnValue.ListElement.TupleElement[1]" and
|
output = "ReturnValue.ListElement.TupleElement[1]" and
|
||||||
preservesValue = true
|
preservesValue = true
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// TODO: Add the keys to output list
|
// TODO: Add the keys to output list
|
||||||
input = "Argument[self]" and
|
input = "Argument[self]" and
|
||||||
@@ -4930,26 +4970,6 @@ module StdlibPrivate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A flow summary for `str.join`. */
|
|
||||||
class StrJoinSummary extends SummarizedCallable::Range {
|
|
||||||
StrJoinSummary() { this = "str.join" }
|
|
||||||
|
|
||||||
override DataFlow::CallCfgNode getACall() { result.(DataFlow::MethodCallNode).calls(_, "join") }
|
|
||||||
|
|
||||||
override DataFlow::ArgumentNode getACallback() {
|
|
||||||
result.(DataFlow::AttrRead).getAttributeName() = "join"
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
||||||
(
|
|
||||||
// For code like `" ".join([name])`
|
|
||||||
input = "Argument[0,iterable:].ListElement" and
|
|
||||||
preservesValue = true
|
|
||||||
) and
|
|
||||||
output = "ReturnValue"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// asyncio
|
// asyncio
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -3,13 +3,4 @@ extensions:
|
|||||||
pack: codeql/python-all
|
pack: codeql/python-all
|
||||||
extensible: sinkModel
|
extensible: sinkModel
|
||||||
data:
|
data:
|
||||||
# Agent instructions, handoff descriptions and tool descriptions are system-level prompts
|
- ['agents', 'Member[Agent].Argument[instructions:]', 'prompt-injection']
|
||||||
- ['agents', 'Member[Agent].Argument[instructions:]', 'system-prompt-injection']
|
|
||||||
- ['agents', 'Member[Agent].Argument[handoff_description:]', 'system-prompt-injection']
|
|
||||||
- ['agents', 'Member[Agent].ReturnValue.Member[as_tool].Argument[1,tool_description:]', 'system-prompt-injection']
|
|
||||||
- ['agents', 'Member[FunctionTool].Argument[description:]', 'system-prompt-injection']
|
|
||||||
# The `@function_tool` decorator's explicit description override is a model-facing instruction
|
|
||||||
- ['agents', 'Member[function_tool].Argument[description_override:]', 'system-prompt-injection']
|
|
||||||
# The input passed to a run is user-level content
|
|
||||||
- ['agents', 'Member[Runner].Member[run,run_sync,run_streamed].Argument[1]', 'user-prompt-injection']
|
|
||||||
- ['agents', 'Member[Runner].Member[run,run_sync,run_streamed].Argument[input:]', 'user-prompt-injection']
|
|
||||||
|
|||||||
@@ -3,18 +3,12 @@ extensions:
|
|||||||
pack: codeql/python-all
|
pack: codeql/python-all
|
||||||
extensible: sinkModel
|
extensible: sinkModel
|
||||||
data:
|
data:
|
||||||
# The `system` field is a system-level prompt
|
- ['Anthropic', 'Member[messages].Member[create].Argument[system:]', 'prompt-injection']
|
||||||
- ['Anthropic', 'Member[messages].Member[create,stream].Argument[system:]', 'system-prompt-injection']
|
- ['Anthropic', 'Member[messages].Member[stream].Argument[system:]', 'prompt-injection']
|
||||||
- ['Anthropic', 'Member[messages].Member[create,stream].Argument[system:].ListElement.DictionaryElement[text]', 'system-prompt-injection']
|
- ['Anthropic', 'Member[beta].Member[messages].Member[create].Argument[system:]', 'prompt-injection']
|
||||||
- ['Anthropic', 'Member[beta].Member[messages].Member[create,stream].Argument[system:]', 'system-prompt-injection']
|
- ['Anthropic', 'Member[messages].Member[create].Argument[messages:].ListElement.DictionaryElement[content]', 'prompt-injection']
|
||||||
- ['Anthropic', 'Member[beta].Member[messages].Member[create,stream].Argument[system:].ListElement.DictionaryElement[text]', 'system-prompt-injection']
|
- ['Anthropic', 'Member[messages].Member[stream].Argument[messages:].ListElement.DictionaryElement[content]', 'prompt-injection']
|
||||||
# The managed agents `system` field is a system-level prompt
|
- ['Anthropic', 'Member[beta].Member[messages].Member[create].Argument[messages:].ListElement.DictionaryElement[content]', 'prompt-injection']
|
||||||
- ['Anthropic', 'Member[beta].Member[agents].Member[create,update].Argument[system:]', 'system-prompt-injection']
|
|
||||||
# A tool description is a model-facing instruction
|
|
||||||
- ['Anthropic', 'Member[messages].Member[create,stream].Argument[tools:].ListElement.DictionaryElement[description]', 'system-prompt-injection']
|
|
||||||
- ['Anthropic', 'Member[beta].Member[messages].Member[create,stream].Argument[tools:].ListElement.DictionaryElement[description]', 'system-prompt-injection']
|
|
||||||
# The legacy Text Completions API `prompt` is user-level content
|
|
||||||
- ['Anthropic', 'Member[completions].Member[create].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
|
|
||||||
- addsTo:
|
- addsTo:
|
||||||
pack: codeql/python-all
|
pack: codeql/python-all
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
extensions:
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: sinkModel
|
|
||||||
data:
|
|
||||||
# `system_instruction` on the generation config is a system-level prompt
|
|
||||||
- ['google', 'Member[genai].Member[types].Member[GenerateContentConfig].Argument[system_instruction:]', 'system-prompt-injection']
|
|
||||||
# The Live API connect config carries a system instruction
|
|
||||||
- ['google', 'Member[genai].Member[types].Member[LiveConnectConfig].Argument[system_instruction:]', 'system-prompt-injection']
|
|
||||||
# Cached content carries a system instruction and user content
|
|
||||||
- ['google', 'Member[genai].Member[types].Member[CreateCachedContentConfig].Argument[system_instruction:]', 'system-prompt-injection']
|
|
||||||
# A tool/function declaration description is a model-facing instruction
|
|
||||||
- ['google', 'Member[genai].Member[types].Member[FunctionDeclaration].Argument[description:]', 'system-prompt-injection']
|
|
||||||
- ['google', 'Member[genai].Member[types].Member[CreateCachedContentConfig].Argument[contents:]', 'user-prompt-injection']
|
|
||||||
# User-level content
|
|
||||||
- ['GoogleGenAI', 'Member[models].Member[generate_content,generate_content_stream].Argument[contents:]', 'user-prompt-injection']
|
|
||||||
- ['GoogleGenAI', 'Member[models].Member[generate_images,generate_videos,edit_image].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
- ['GoogleGenAI', 'Member[chats].Member[create].ReturnValue.Member[send_message,send_message_stream].Argument[0]', 'user-prompt-injection']
|
|
||||||
- ['GoogleGenAI', 'Member[chats].Member[create].ReturnValue.Member[send_message,send_message_stream].Argument[message:]', 'user-prompt-injection']
|
|
||||||
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: typeModel
|
|
||||||
data:
|
|
||||||
- ['GoogleGenAI', 'google', 'Member[genai].Member[Client].ReturnValue']
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
extensions:
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: sinkModel
|
|
||||||
data:
|
|
||||||
# Message constructors. The first positional argument or the `content` keyword
|
|
||||||
# carries the message text.
|
|
||||||
- ['langchain_core', 'Member[messages].Member[SystemMessage].Argument[0]', 'system-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[messages].Member[SystemMessage].Argument[content:]', 'system-prompt-injection']
|
|
||||||
- ['langchain', 'Member[schema].Member[SystemMessage].Argument[0]', 'system-prompt-injection']
|
|
||||||
- ['langchain', 'Member[schema].Member[SystemMessage].Argument[content:]', 'system-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[messages].Member[HumanMessage].Argument[0]', 'user-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[messages].Member[HumanMessage].Argument[content:]', 'user-prompt-injection']
|
|
||||||
- ['langchain', 'Member[schema].Member[HumanMessage].Argument[0]', 'user-prompt-injection']
|
|
||||||
- ['langchain', 'Member[schema].Member[HumanMessage].Argument[content:]', 'user-prompt-injection']
|
|
||||||
# Invoking a chat model with user input.
|
|
||||||
- ['LangChainChatModel', 'Member[invoke,stream,predict,call].Argument[0]', 'user-prompt-injection']
|
|
||||||
- ['LangChainChatModel', 'Member[batch].Argument[0].ListElement', 'user-prompt-injection']
|
|
||||||
- ['LangChainChatModel', 'Member[generate].Argument[0].ListElement.ListElement', 'user-prompt-injection']
|
|
||||||
# Prompt templates. User input embedded directly into a template.
|
|
||||||
- ['langchain_core', 'Member[prompts].Member[PromptTemplate].Instance.Member[format].Argument[any-named]', 'user-prompt-injection']
|
|
||||||
# Legacy `LLMChain` and `AgentExecutor` take the user input in the `input` field.
|
|
||||||
- ['LangChainLLMChain', 'Member[invoke].Argument[0].DictionaryElement[input]', 'user-prompt-injection']
|
|
||||||
- ['LangChainLLMChain', 'Member[run].Argument[0]', 'user-prompt-injection']
|
|
||||||
- ['LangChainAgentExecutor', 'Member[invoke].Argument[0].DictionaryElement[input]', 'user-prompt-injection']
|
|
||||||
# The `system_prompt` passed to `create_agent` is a system-level prompt.
|
|
||||||
- ['langchain', 'Member[agents].Member[create_agent].Argument[system_prompt:]', 'system-prompt-injection']
|
|
||||||
# The messages passed to a `create_agent` graph are user-level content.
|
|
||||||
- ['LangChainAgent', 'Member[invoke,stream].Argument[0].DictionaryElement[messages].ListElement.DictionaryElement[content]', 'user-prompt-injection']
|
|
||||||
# A tool description is a model-facing instruction.
|
|
||||||
- ['langchain_core', 'Member[tools].Member[Tool].Argument[2,description:]', 'system-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[tools].Member[Tool].Member[from_function].Argument[2,description:]', 'system-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[tools].Member[StructuredTool].Argument[description:]', 'system-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[tools].Member[StructuredTool].Member[from_function].Argument[description:]', 'system-prompt-injection']
|
|
||||||
- ['langchain_core', 'Member[tools].Member[tool].Argument[description:]', 'system-prompt-injection']
|
|
||||||
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: typeModel
|
|
||||||
data:
|
|
||||||
- ['LangChainChatModel', 'langchain_openai', 'Member[ChatOpenAI,AzureChatOpenAI].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_anthropic', 'Member[ChatAnthropic].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_google_genai', 'Member[ChatGoogleGenerativeAI].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_mistralai', 'Member[ChatMistralAI].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_groq', 'Member[ChatGroq].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_cohere', 'Member[ChatCohere].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_ollama', 'Member[ChatOllama].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_aws', 'Member[ChatBedrock,ChatBedrockConverse].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_fireworks', 'Member[ChatFireworks].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_together', 'Member[ChatTogether].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain_xai', 'Member[ChatXAI].ReturnValue']
|
|
||||||
- ['LangChainChatModel', 'langchain', 'Member[chat_models].Member[init_chat_model].ReturnValue']
|
|
||||||
- ['LangChainLLMChain', 'langchain', 'Member[chains].Member[LLMChain].ReturnValue']
|
|
||||||
- ['LangChainLLMChain', 'langchain_classic', 'Member[chains].Member[LLMChain].ReturnValue']
|
|
||||||
- ['LangChainAgentExecutor', 'langchain', 'Member[agents].Member[AgentExecutor].ReturnValue']
|
|
||||||
- ['LangChainAgentExecutor', 'langchain_classic', 'Member[agents].Member[AgentExecutor].ReturnValue']
|
|
||||||
- ['LangChainAgentExecutor', 'langchain', 'Member[agents].Member[AgentExecutor].Member[from_agent_and_tools].ReturnValue']
|
|
||||||
- ['LangChainAgentExecutor', 'langchain_classic', 'Member[agents].Member[AgentExecutor].Member[from_agent_and_tools].ReturnValue']
|
|
||||||
- ['LangChainAgent', 'langchain', 'Member[agents].Member[create_agent].ReturnValue']
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
extensions:
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: summaryModel
|
|
||||||
data:
|
|
||||||
- ['lxml', 'Member[etree].Member[fromstringlist]', 'Argument[0,strings:].ListElement', 'ReturnValue', 'taint']
|
|
||||||
@@ -3,24 +3,10 @@ extensions:
|
|||||||
pack: codeql/python-all
|
pack: codeql/python-all
|
||||||
extensible: sinkModel
|
extensible: sinkModel
|
||||||
data:
|
data:
|
||||||
# System-level prompts and instructions
|
- ['OpenAI', 'Member[beta].Member[assistants].Member[create].Argument[instructions:]', 'prompt-injection']
|
||||||
- ['OpenAI', 'Member[responses].Member[create].Argument[instructions:]', 'system-prompt-injection']
|
- ['OpenAI', 'Member[chat].Member[completions].Member[create].Argument[messages:].ListElement.DictionaryElement[content]', 'prompt-injection']
|
||||||
- ['OpenAI', 'Member[beta].Member[assistants].Member[create].Argument[instructions:]', 'system-prompt-injection']
|
- ['OpenAI', 'Member[responses].Member[create].Argument[instructions:]', 'prompt-injection']
|
||||||
- ['OpenAI', 'Member[beta].Member[assistants].Member[update].Argument[instructions:]', 'system-prompt-injection']
|
- ['OpenAI', 'Member[responses].Member[create].Argument[input:]', 'prompt-injection']
|
||||||
- ['OpenAI', 'Member[beta].Member[threads].Member[runs].Member[create].Argument[instructions:]', 'system-prompt-injection']
|
|
||||||
- ['OpenAI', 'Member[beta].Member[threads].Member[runs].Member[create].Argument[additional_instructions:]', 'system-prompt-injection']
|
|
||||||
# The default system instructions for a realtime session
|
|
||||||
- ['OpenAI', 'Member[beta].Member[realtime].Member[sessions].Member[create].Argument[instructions:]', 'system-prompt-injection']
|
|
||||||
# A tool/function description is a model-facing instruction
|
|
||||||
- ['OpenAI', 'Member[chat].Member[completions].Member[create].Argument[tools:].ListElement.DictionaryElement[function].DictionaryElement[description]', 'system-prompt-injection']
|
|
||||||
- ['OpenAI', 'Member[responses].Member[create].Argument[tools:].ListElement.DictionaryElement[description]', 'system-prompt-injection']
|
|
||||||
# User-level prompts
|
|
||||||
- ['OpenAI', 'Member[responses].Member[create].Argument[input:]', 'user-prompt-injection']
|
|
||||||
- ['OpenAI', 'Member[completions].Member[create].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
- ['OpenAI', 'Member[images].Member[generate,edit].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
- ['OpenAI', 'Member[audio].Member[transcriptions,translations].Member[create].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
# Sora video generation prompts are user-level content
|
|
||||||
- ['OpenAI', 'Member[videos].Member[create,create_and_poll,edit,remix,extend].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
|
|
||||||
- addsTo:
|
- addsTo:
|
||||||
pack: codeql/python-all
|
pack: codeql/python-all
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
extensions:
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: sinkModel
|
|
||||||
data:
|
|
||||||
# `responses.send` instructions is a system-level prompt; input is user content
|
|
||||||
- ['OpenRouter', 'Member[responses].Member[send].Argument[instructions:]', 'system-prompt-injection']
|
|
||||||
- ['OpenRouter', 'Member[responses].Member[send].Argument[input:]', 'user-prompt-injection']
|
|
||||||
# A tool/function description passed to `chat.send` is a model-facing instruction
|
|
||||||
- ['OpenRouter', 'Member[chat].Member[send].Argument[tools:].ListElement.DictionaryElement[function].DictionaryElement[description]', 'system-prompt-injection']
|
|
||||||
# Embeddings input is user-level content
|
|
||||||
- ['OpenRouter', 'Member[embeddings].Member[generate].Argument[input:]', 'user-prompt-injection']
|
|
||||||
# Image, video and speech generation prompts are user-level content
|
|
||||||
- ['OpenRouter', 'Member[images].Member[generate].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
- ['OpenRouter', 'Member[video_generation].Member[generate].Argument[prompt:]', 'user-prompt-injection']
|
|
||||||
- ['OpenRouter', 'Member[tts].Member[create_speech].Argument[input:]', 'user-prompt-injection']
|
|
||||||
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: typeModel
|
|
||||||
data:
|
|
||||||
- ['OpenRouter', 'openrouter', 'Member[OpenRouter].ReturnValue']
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
extensions:
|
|
||||||
- addsTo:
|
|
||||||
pack: codeql/python-all
|
|
||||||
extensible: summaryModel
|
|
||||||
data:
|
|
||||||
- ['xml', 'Member[etree].Member[fromstringlist]', 'Argument[0,strings:].ListElement', 'ReturnValue', 'taint']
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides default sources, sinks and sanitizers for detecting
|
|
||||||
* "system prompt injection"
|
|
||||||
* vulnerabilities, as well as extension points for adding your own.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import python
|
|
||||||
private import semmle.python.Concepts
|
|
||||||
private import semmle.python.ApiGraphs
|
|
||||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
|
||||||
private import semmle.python.dataflow.new.BarrierGuards
|
|
||||||
private import semmle.python.frameworks.data.ModelsAsData
|
|
||||||
private import semmle.python.frameworks.OpenAI
|
|
||||||
private import semmle.python.frameworks.Anthropic
|
|
||||||
private import semmle.python.frameworks.GoogleGenAI
|
|
||||||
private import semmle.python.frameworks.OpenRouter
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides default sources, sinks and sanitizers for detecting
|
|
||||||
* "system prompt injection"
|
|
||||||
* vulnerabilities, as well as extension points for adding your own.
|
|
||||||
*/
|
|
||||||
module SystemPromptInjection {
|
|
||||||
/**
|
|
||||||
* A data flow source for "system prompt injection" vulnerabilities.
|
|
||||||
*/
|
|
||||||
abstract class Source extends DataFlow::Node { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A data flow sink for "system prompt injection" vulnerabilities.
|
|
||||||
*/
|
|
||||||
abstract class Sink extends DataFlow::Node { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A sanitizer for "system prompt injection" vulnerabilities.
|
|
||||||
*/
|
|
||||||
abstract class Sanitizer extends DataFlow::Node { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An active threat-model source, considered as a flow source.
|
|
||||||
*/
|
|
||||||
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A prompt to an AI model, considered as a flow sink.
|
|
||||||
*/
|
|
||||||
class AIPromptAsSink extends Sink {
|
|
||||||
AIPromptAsSink() { this = any(AIPrompt p).getAPrompt() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SinkFromModel extends Sink {
|
|
||||||
SinkFromModel() { this = ModelOutput::getASinkNode("system-prompt-injection").asSink() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PromptContentSink extends Sink {
|
|
||||||
PromptContentSink() {
|
|
||||||
this = OpenAI::getSystemOrAssistantPromptNode().asSink()
|
|
||||||
or
|
|
||||||
this = AgentSdk::getSystemOrAssistantPromptNode().asSink()
|
|
||||||
or
|
|
||||||
this = Anthropic::getSystemOrAssistantPromptNode().asSink()
|
|
||||||
or
|
|
||||||
this = GoogleGenAI::getSystemOrAssistantPromptNode().asSink()
|
|
||||||
or
|
|
||||||
this = OpenRouter::getSystemOrAssistantPromptNode().asSink()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Content placed in a message with `role: "user"` is not a system prompt
|
|
||||||
* injection vector; it is intended user-role content.
|
|
||||||
*
|
|
||||||
* This prevents false positives when user input and system prompts are
|
|
||||||
* combined in the same message list and taint would otherwise propagate to
|
|
||||||
* the system message.
|
|
||||||
*/
|
|
||||||
private class UserRoleMessageContentBarrier extends Sanitizer {
|
|
||||||
UserRoleMessageContentBarrier() {
|
|
||||||
exists(API::Node msg |
|
|
||||||
msg.getSubscript("role").getAValueReachingSink().asExpr().(StringLiteral).getText() = "user"
|
|
||||||
|
|
|
||||||
this = msg.getSubscript("content").asSink()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A comparison with a constant, considered as a sanitizer-guard.
|
|
||||||
*/
|
|
||||||
class ConstCompareAsSanitizerGuard extends Sanitizer, ConstCompareBarrier { }
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides a taint-tracking configuration for detecting "system prompt injection" vulnerabilities.
|
|
||||||
*
|
|
||||||
* Note, for performance reasons: only import this file if
|
|
||||||
* `SystemPromptInjection::Configuration` is needed, otherwise
|
|
||||||
* `SystemPromptInjectionCustomizations` should be imported instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import python
|
|
||||||
import semmle.python.dataflow.new.DataFlow
|
|
||||||
import semmle.python.dataflow.new.TaintTracking
|
|
||||||
import SystemPromptInjectionCustomizations::SystemPromptInjection
|
|
||||||
|
|
||||||
private module SystemPromptInjectionConfig implements DataFlow::ConfigSig {
|
|
||||||
predicate isSource(DataFlow::Node node) { node instanceof Source }
|
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node node) { node instanceof Sink }
|
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
|
||||||
|
|
||||||
predicate observeDiffInformedIncrementalMode() { any() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Global taint-tracking for detecting "system prompt injection" vulnerabilities. */
|
|
||||||
module SystemPromptInjectionFlow = TaintTracking::Global<SystemPromptInjectionConfig>;
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides a taint-tracking configuration for detecting "user prompt injection" vulnerabilities.
|
|
||||||
*
|
|
||||||
* Note, for performance reasons: only import this file if
|
|
||||||
* `UserPromptInjection::Configuration` is needed, otherwise
|
|
||||||
* `UserPromptInjectionCustomizations` should be imported instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import python
|
|
||||||
import semmle.python.dataflow.new.DataFlow
|
|
||||||
import semmle.python.dataflow.new.TaintTracking
|
|
||||||
import UserPromptInjectionCustomizations::UserPromptInjection
|
|
||||||
|
|
||||||
private module UserPromptInjectionConfig implements DataFlow::ConfigSig {
|
|
||||||
predicate isSource(DataFlow::Node node) { node instanceof Source }
|
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node node) { node instanceof Sink }
|
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
|
||||||
|
|
||||||
predicate observeDiffInformedIncrementalMode() { any() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Global taint-tracking for detecting "user prompt injection" vulnerabilities. */
|
|
||||||
module UserPromptInjectionFlow = TaintTracking::Global<UserPromptInjectionConfig>;
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<!DOCTYPE qhelp PUBLIC
|
|
||||||
"-//Semmle//qhelp//EN"
|
|
||||||
"qhelp.dtd">
|
|
||||||
<qhelp>
|
|
||||||
|
|
||||||
<overview>
|
|
||||||
<p>If user-controlled data is included in a system prompt or the description of tools for an agentic system, an attacker can manipulate the instructions
|
|
||||||
that govern the AI model's behavior, bypassing intended restrictions and potentially causing sensitive
|
|
||||||
data leaks or unintended operations.
|
|
||||||
</p>
|
|
||||||
</overview>
|
|
||||||
|
|
||||||
<recommendation>
|
|
||||||
<p>Do not include user input in system-level or developer-level prompts or tool descriptions. Use methods meant for user input or messages with a "user" role to provide user content or context to the AI model.
|
|
||||||
|
|
||||||
If user input must influence the system prompt or tool description, validate it against a fixed allowlist of permitted values.</p>
|
|
||||||
</recommendation>
|
|
||||||
|
|
||||||
<example>
|
|
||||||
<p>In the following example, a user-controlled value is inserted directly into a system-level prompt
|
|
||||||
without validation, allowing an attacker to manipulate the AI's behavior.</p>
|
|
||||||
<sample src="examples/prompt-injection.py" />
|
|
||||||
<p>One way to fix this is to provide the user-controlled value in a message with the "user" role,
|
|
||||||
rather than including it in the system prompt. The model then treats it as user content instead of
|
|
||||||
as a trusted instruction.</p>
|
|
||||||
<sample src="examples/prompt-injection_fixed_user_role.py" />
|
|
||||||
<p>Alternatively, if the user input must influence the system prompt, validate it against a fixed
|
|
||||||
allowlist of permitted values before including it in the prompt.</p>
|
|
||||||
<sample src="examples/prompt-injection_fixed.py" />
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<example>
|
|
||||||
<p>Prompt injection is not limited to system prompts. In the following example, which uses an agentic
|
|
||||||
framework, a user-controlled value is included in the description of a tool that is exposed to the
|
|
||||||
model. An attacker can use this to manipulate the model's behavior in the same way.</p>
|
|
||||||
<sample src="examples/tool-description-injection.py" />
|
|
||||||
<p>The fix keeps the tool description as a fixed, trusted string and passes the user-controlled topic
|
|
||||||
as part of the user input instead, so the model treats it as user content rather than as a trusted
|
|
||||||
instruction.</p>
|
|
||||||
<sample src="examples/tool-description-injection_fixed.py" />
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<references>
|
|
||||||
<li>OWASP: <a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">LLM01: Prompt Injection</a>.</li>
|
|
||||||
<li>MITRE CWE: <a href="https://cwe.mitre.org/data/definitions/1427.html">CWE-1427: Improper Neutralization of Input Used for LLM Prompting</a>.</li>
|
|
||||||
</references>
|
|
||||||
|
|
||||||
</qhelp>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* @name System prompt injection
|
|
||||||
* @description Untrusted input flowing into a system prompt, developer prompt, or tool description
|
|
||||||
* of an AI model may allow an attacker to manipulate the model's behavior.
|
|
||||||
* @kind path-problem
|
|
||||||
* @problem.severity error
|
|
||||||
* @security-severity 7.8
|
|
||||||
* @precision high
|
|
||||||
* @id py/system-prompt-injection
|
|
||||||
* @tags security
|
|
||||||
* external/cwe/cwe-1427
|
|
||||||
*/
|
|
||||||
|
|
||||||
import python
|
|
||||||
import semmle.python.security.dataflow.SystemPromptInjectionQuery
|
|
||||||
import SystemPromptInjectionFlow::PathGraph
|
|
||||||
|
|
||||||
from SystemPromptInjectionFlow::PathNode source, SystemPromptInjectionFlow::PathNode sink
|
|
||||||
where SystemPromptInjectionFlow::flowPath(source, sink)
|
|
||||||
select sink.getNode(), source, sink, "This system prompt depends on a $@.", source.getNode(),
|
|
||||||
"user-provided value"
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<!DOCTYPE qhelp PUBLIC
|
|
||||||
"-//Semmle//qhelp//EN"
|
|
||||||
"qhelp.dtd">
|
|
||||||
<qhelp>
|
|
||||||
|
|
||||||
<overview>
|
|
||||||
<p>If untrusted input is included in a user-role prompt sent to an AI model, an attacker can inject
|
|
||||||
instructions that manipulate the model's behavior. This is known as <i>indirect prompt injection</i>
|
|
||||||
when the malicious content arrives through data the model processes, or <i>direct prompt injection</i>
|
|
||||||
when the attacker controls the prompt directly.</p>
|
|
||||||
|
|
||||||
<p>Unlike system prompt injection, user prompt injection targets the user-role messages. Although
|
|
||||||
user messages are expected to carry user input, passing unsanitized data directly into structured
|
|
||||||
prompt templates can still allow an attacker to override intended instructions, extract sensitive
|
|
||||||
context, or trigger unintended tool calls.</p>
|
|
||||||
</overview>
|
|
||||||
|
|
||||||
<recommendation>
|
|
||||||
<p>To mitigate user prompt injection:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Ensure that all data flowing into user input is intended and necessary for the purpose of the AI system.</li>
|
|
||||||
<li>Ensure the system prompt clearly describes the purpose, scope and boundaries of the AI system. Instruct the system to deny input that falls outside these boundaries.</li>
|
|
||||||
<li>If creating a prompt out of multiple user-controlled values, assume that each of them can be malicious. Ensure the range of possible values is restricted and validated.
|
|
||||||
For example, if a prompt includes a question and the intended language to respond in, validate that the language is one of the supported options.</li>
|
|
||||||
<li>Consider using guardrails on the input like the OpenAI guardrails library to enforce constraints and prevent malicious content from being processed.</li>
|
|
||||||
<li>Apply output filtering to detect and block responses that indicate prompt injection attempts.</li>
|
|
||||||
</ul>
|
|
||||||
</recommendation>
|
|
||||||
|
|
||||||
<example>
|
|
||||||
<p>In the following example, user-controlled data is inserted directly into a user-role prompt
|
|
||||||
without any validation, allowing an attacker to inject arbitrary instructions.</p>
|
|
||||||
<sample src="examples/user-prompt-injection.py" />
|
|
||||||
|
|
||||||
<p>The following example applies multiple mitigations together, and only includes data that is
|
|
||||||
necessary for the task in the prompt: the value that selects behavior (the response language) is
|
|
||||||
validated against a fixed allowlist before it is used, and the system prompt clearly describes the
|
|
||||||
assistant's scope and instructs it to ignore embedded instructions.</p>
|
|
||||||
<sample src="examples/user-prompt-injection_fixed.py" />
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<references>
|
|
||||||
<li>OWASP: <a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">LLM01: Prompt Injection</a>.</li>
|
|
||||||
<li>MITRE CWE: <a href="https://cwe.mitre.org/data/definitions/1427.html">CWE-1427: Improper Neutralization of Input Used for LLM Prompting</a>.</li>
|
|
||||||
</references>
|
|
||||||
|
|
||||||
</qhelp>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* @name User prompt injection
|
|
||||||
* @description Untrusted input flowing into a user-role prompt of an AI model
|
|
||||||
* may allow an attacker to manipulate the model's behavior.
|
|
||||||
* @kind path-problem
|
|
||||||
* @problem.severity warning
|
|
||||||
* @security-severity 5.0
|
|
||||||
* @precision low
|
|
||||||
* @id py/user-prompt-injection
|
|
||||||
* @tags security
|
|
||||||
* external/cwe/cwe-1427
|
|
||||||
*/
|
|
||||||
|
|
||||||
import python
|
|
||||||
import semmle.python.security.dataflow.UserPromptInjectionQuery
|
|
||||||
import UserPromptInjectionFlow::PathGraph
|
|
||||||
|
|
||||||
from UserPromptInjectionFlow::PathNode source, UserPromptInjectionFlow::PathNode sink
|
|
||||||
where UserPromptInjectionFlow::flowPath(source, sink)
|
|
||||||
select sink.getNode(), source, sink, "This prompt construction depends on a $@.", source.getNode(),
|
|
||||||
"user-provided value"
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from flask import Flask, request
|
|
||||||
from openai import OpenAI
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
client = OpenAI()
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/chat")
|
|
||||||
def chat():
|
|
||||||
persona = request.args.get("persona")
|
|
||||||
|
|
||||||
# BAD: user input is used directly in a system-level prompt
|
|
||||||
response = client.chat.completions.create(
|
|
||||||
model="gpt-4.1",
|
|
||||||
messages=[
|
|
||||||
{
|
|
||||||
"role": "system",
|
|
||||||
"content": "You are a helpful assistant. Act as a " + persona,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": request.args.get("message"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
return response
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user