Merge branch 'main' into jcogs33/update-externalapi-charpredicate

This commit is contained in:
Jami
2022-12-12 16:01:22 -05:00
committed by GitHub
329 changed files with 5786 additions and 3464 deletions

21
.github/workflows/check-query-ids.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Check query IDs
on:
pull_request:
paths:
- "**/src/**/*.ql"
- misc/scripts/check-query-ids.py
- .github/workflows/check-query-ids.yml
branches:
- main
- "rc/*"
workflow_dispatch:
jobs:
check:
name: Check query IDs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check for duplicate query IDs
run: python3 misc/scripts/check-query-ids.py

View File

@@ -65,6 +65,7 @@ jobs:
if : ${{ github.event_name == 'pull_request' }} if : ${{ github.event_name == 'pull_request' }}
needs: build-and-test-macos needs: build-and-test-macos
runs-on: macos-12-xl runs-on: macos-12-xl
timeout-minutes: 60
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: ./swift/actions/run-integration-tests - uses: ./swift/actions/run-integration-tests

View File

@@ -470,6 +470,10 @@
"javascript/ql/src/Comments/CommentedOutCodeReferences.inc.qhelp", "javascript/ql/src/Comments/CommentedOutCodeReferences.inc.qhelp",
"python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp" "python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp"
], ],
"ThreadResourceAbuse qhelp": [
"java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp",
"java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp"
],
"IDE Contextual Queries": [ "IDE Contextual Queries": [
"cpp/ql/lib/IDEContextual.qll", "cpp/ql/lib/IDEContextual.qll",
"csharp/ql/lib/IDEContextual.qll", "csharp/ql/lib/IDEContextual.qll",
@@ -537,6 +541,11 @@
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll", "ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll",
"python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll" "python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll"
], ],
"ApiGraphModelsExtensions": [
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsExtensions.qll",
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsExtensions.qll",
"python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsExtensions.qll"
],
"TaintedFormatStringQuery Ruby/JS": [ "TaintedFormatStringQuery Ruby/JS": [
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll", "javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll",
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll" "ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll"

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `getaddrinfo` function is now recognized as a flow source.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `scanf` and `fscanf` functions and their variants are now recognized as flow sources.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `ArgvSource` flow source has been generalized to handle cases where the argument vector of `main` is not named `argv`.

View File

@@ -27,7 +27,7 @@ private import implementations.StdString
private import implementations.Swap private import implementations.Swap
private import implementations.GetDelim private import implementations.GetDelim
private import implementations.SmartPointer private import implementations.SmartPointer
private import implementations.Sscanf private import implementations.Scanf
private import implementations.Send private import implementations.Send
private import implementations.Recv private import implementations.Recv
private import implementations.Accept private import implementations.Accept

View File

@@ -15,6 +15,6 @@ private class Fread extends AliasFunction, RemoteFlowSourceFunction {
override predicate hasRemoteFlowSource(FunctionOutput output, string description) { override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and output.isParameterDeref(0) and
description = "String read by " + this.getName() description = "string read by " + this.getName()
} }
} }

View File

@@ -36,6 +36,6 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF
override predicate hasRemoteFlowSource(FunctionOutput output, string description) { override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and output.isParameterDeref(0) and
description = "String read by " + this.getName() description = "string read by " + this.getName()
} }
} }

View File

@@ -49,10 +49,10 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
override predicate hasRemoteFlowSource(FunctionOutput output, string description) { override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and output.isParameterDeref(0) and
description = "String read by " + this.getName() description = "string read by " + this.getName()
or or
output.isReturnValue() and output.isReturnValue() and
description = "String read by " + this.getName() description = "string read by " + this.getName()
} }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) { override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
@@ -98,10 +98,10 @@ private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunctio
override predicate hasLocalFlowSource(FunctionOutput output, string description) { override predicate hasLocalFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and output.isParameterDeref(0) and
description = "String read by " + this.getName() description = "string read by " + this.getName()
or or
output.isReturnValue() and output.isReturnValue() and
description = "String read by " + this.getName() description = "string read by " + this.getName()
} }
override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = 0 } override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = 0 }

View File

@@ -1,9 +1,10 @@
import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.FlowSource
private class InetNtoa extends TaintFunction { private class InetNtoa extends TaintFunction {
InetNtoa() { hasGlobalName("inet_ntoa") } InetNtoa() { this.hasGlobalName("inet_ntoa") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and input.isParameter(0) and
@@ -12,7 +13,7 @@ private class InetNtoa extends TaintFunction {
} }
private class InetAton extends TaintFunction, ArrayFunction { private class InetAton extends TaintFunction, ArrayFunction {
InetAton() { hasGlobalName("inet_aton") } InetAton() { this.hasGlobalName("inet_aton") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and input.isParameterDeref(0) and
@@ -32,7 +33,7 @@ private class InetAton extends TaintFunction, ArrayFunction {
} }
private class InetAddr extends TaintFunction, ArrayFunction, AliasFunction { private class InetAddr extends TaintFunction, ArrayFunction, AliasFunction {
InetAddr() { hasGlobalName("inet_addr") } InetAddr() { this.hasGlobalName("inet_addr") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and input.isParameterDeref(0) and
@@ -51,7 +52,7 @@ private class InetAddr extends TaintFunction, ArrayFunction, AliasFunction {
} }
private class InetNetwork extends TaintFunction, ArrayFunction { private class InetNetwork extends TaintFunction, ArrayFunction {
InetNetwork() { hasGlobalName("inet_network") } InetNetwork() { this.hasGlobalName("inet_network") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and input.isParameterDeref(0) and
@@ -64,7 +65,7 @@ private class InetNetwork extends TaintFunction, ArrayFunction {
} }
private class InetMakeaddr extends TaintFunction { private class InetMakeaddr extends TaintFunction {
InetMakeaddr() { hasGlobalName("inet_makeaddr") } InetMakeaddr() { this.hasGlobalName("inet_makeaddr") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
( (
@@ -76,7 +77,7 @@ private class InetMakeaddr extends TaintFunction {
} }
private class InetLnaof extends TaintFunction { private class InetLnaof extends TaintFunction {
InetLnaof() { hasGlobalName("inet_lnaof") } InetLnaof() { this.hasGlobalName("inet_lnaof") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and input.isParameter(0) and
@@ -85,7 +86,7 @@ private class InetLnaof extends TaintFunction {
} }
private class InetNetof extends TaintFunction { private class InetNetof extends TaintFunction {
InetNetof() { hasGlobalName("inet_netof") } InetNetof() { this.hasGlobalName("inet_netof") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and input.isParameter(0) and
@@ -94,7 +95,7 @@ private class InetNetof extends TaintFunction {
} }
private class InetPton extends TaintFunction, ArrayFunction { private class InetPton extends TaintFunction, ArrayFunction {
InetPton() { hasGlobalName("inet_pton") } InetPton() { this.hasGlobalName("inet_pton") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
( (
@@ -114,7 +115,7 @@ private class InetPton extends TaintFunction, ArrayFunction {
} }
private class Gethostbyname extends TaintFunction, ArrayFunction { private class Gethostbyname extends TaintFunction, ArrayFunction {
Gethostbyname() { hasGlobalName("gethostbyname") } Gethostbyname() { this.hasGlobalName("gethostbyname") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and input.isParameterDeref(0) and
@@ -127,7 +128,7 @@ private class Gethostbyname extends TaintFunction, ArrayFunction {
} }
private class Gethostbyaddr extends TaintFunction, ArrayFunction { private class Gethostbyaddr extends TaintFunction, ArrayFunction {
Gethostbyaddr() { hasGlobalName("gethostbyaddr") } Gethostbyaddr() { this.hasGlobalName("gethostbyaddr") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
( (
@@ -142,3 +143,21 @@ private class Gethostbyaddr extends TaintFunction, ArrayFunction {
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 } override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 }
} }
private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSourceFunction {
Getaddrinfo() { this.hasGlobalName("getaddrinfo") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref([0 .. 2]) and
output.isParameterDeref(3)
}
override predicate hasArrayInput(int bufParam) { bufParam in [0, 1] }
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam in [0, 1] }
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(3) and
description = "address returned by " + this.getName()
}
}

View File

@@ -83,7 +83,7 @@ private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction,
or or
this.hasGlobalName("recvfrom") and output.isParameterDeref([4, 5]) this.hasGlobalName("recvfrom") and output.isParameterDeref([4, 5])
) and ) and
description = "Buffer read by " + this.getName() description = "buffer read by " + this.getName()
} }
override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) } override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }

View File

@@ -1,6 +1,6 @@
/** /**
* Provides implementation classes modeling `sscanf`, `fscanf` and various similar * Provides implementation classes modeling the `scanf` family of functions.
* functions. See `semmle.code.cpp.models.Models` for usage information. * See `semmle.code.cpp.models.Models` for usage information.
*/ */
import semmle.code.cpp.Function import semmle.code.cpp.Function
@@ -9,18 +9,15 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.FlowSource
/** /**
* The standard function `sscanf`, `fscanf` and its assorted variants * The `scanf` family of functions.
*/ */
private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction { abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction, AliasFunction,
SscanfModel() { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf } SideEffectFunction {
override predicate hasArrayWithNullTerminator(int bufParam) { override predicate hasArrayWithNullTerminator(int bufParam) {
bufParam = this.(ScanfFunction).getFormatParameterIndex() bufParam = this.(ScanfFunction).getFormatParameterIndex()
or
not this instanceof Fscanf and
bufParam = this.(ScanfFunction).getInputParameterIndex()
} }
override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) } override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) }
@@ -36,7 +33,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
) )
} }
private int getArgsStartPosition() { result = this.getNumberOfParameters() } int getArgsStartPosition() { result = this.getNumberOfParameters() }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and
@@ -70,3 +67,36 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
] ]
} }
} }
/**
* The standard function `scanf` and its assorted variants
*/
private class ScanfModel extends ScanfFunctionModel, LocalFlowSourceFunction instanceof Scanf {
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and
description = "value read by " + this.getName()
}
}
/**
* The standard function `fscanf` and its assorted variants
*/
private class FscanfModel extends ScanfFunctionModel, RemoteFlowSourceFunction instanceof Fscanf {
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and
description = "value read by " + this.getName()
}
}
/**
* The standard function `sscanf` and its assorted variants
*/
private class SscanfModel extends ScanfFunctionModel {
SscanfModel() { this instanceof Sscanf or this instanceof Snscanf }
override predicate hasArrayWithNullTerminator(int bufParam) {
super.hasArrayWithNullTerminator(bufParam)
or
bufParam = this.(ScanfFunction).getInputParameterIndex()
}
}

View File

@@ -58,7 +58,7 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 } override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
override predicate hasRemoteFlowSink(FunctionInput input, string description) { override predicate hasRemoteFlowSink(FunctionInput input, string description) {
input.isParameterDeref(1) and description = "Buffer sent by " + this.getName() input.isParameterDeref(1) and description = "buffer sent by " + this.getName()
} }
override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) } override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }

View File

@@ -89,9 +89,9 @@ private class LocalParameterSource extends LocalFlowSource {
private class ArgvSource extends LocalFlowSource { private class ArgvSource extends LocalFlowSource {
ArgvSource() { ArgvSource() {
exists(Parameter argv | exists(Function main, Parameter argv |
argv.hasName("argv") and main.hasGlobalName("main") and
argv.getFunction().hasGlobalName("main") and main.getParameter(1) = argv and
this.asExpr() = argv.getAnAccess() this.asExpr() = argv.getAnAccess()
) )
} }

View File

@@ -16,7 +16,7 @@
import cpp import cpp
import semmle.code.cpp.security.FunctionWithWrappers import semmle.code.cpp.security.FunctionWithWrappers
import semmle.code.cpp.security.Security import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.ir.dataflow.TaintTracking
import DataFlow::PathGraph import DataFlow::PathGraph
@@ -47,12 +47,6 @@ class FileFunction extends FunctionWithWrappers {
override predicate interestingArg(int arg) { arg = 0 } override predicate interestingArg(int arg) { arg = 0 }
} }
Expr asSourceExpr(DataFlow::Node node) {
result = node.asConvertedExpr()
or
result = node.asDefiningArgument()
}
Expr asSinkExpr(DataFlow::Node node) { Expr asSinkExpr(DataFlow::Node node) {
result = result =
node.asOperand() node.asOperand()
@@ -89,7 +83,7 @@ predicate hasUpperBoundsCheck(Variable var) {
class TaintedPathConfiguration extends TaintTracking::Configuration { class TaintedPathConfiguration extends TaintTracking::Configuration {
TaintedPathConfiguration() { this = "TaintedPathConfiguration" } TaintedPathConfiguration() { this = "TaintedPathConfiguration" }
override predicate isSource(DataFlow::Node node) { isUserInput(asSourceExpr(node), _) } override predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
override predicate isSink(DataFlow::Node node) { override predicate isSink(DataFlow::Node node) {
exists(FileFunction fileFunction | exists(FileFunction fileFunction |
@@ -108,31 +102,16 @@ class TaintedPathConfiguration extends TaintTracking::Configuration {
hasUpperBoundsCheck(checkedVar) hasUpperBoundsCheck(checkedVar)
) )
} }
predicate hasFilteredFlowPath(DataFlow::PathNode source, DataFlow::PathNode sink) {
this.hasFlowPath(source, sink) and
// The use of `isUserInput` in `isSink` in combination with `asSourceExpr` causes
// duplicate results. Filter these duplicates. The proper solution is to switch to
// using `LocalFlowSource` and `RemoteFlowSource`, but this currently only supports
// a subset of the cases supported by `isUserInput`.
not exists(DataFlow::PathNode source2 |
this.hasFlowPath(source2, sink) and
asSourceExpr(source.getNode()) = asSourceExpr(source2.getNode())
|
not exists(source.getNode().asConvertedExpr()) and exists(source2.getNode().asConvertedExpr())
)
}
} }
from from
FileFunction fileFunction, Expr taintedArg, Expr taintSource, TaintedPathConfiguration cfg, FileFunction fileFunction, Expr taintedArg, FlowSource taintSource, TaintedPathConfiguration cfg,
DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, string taintCause, string callChain DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, string callChain
where where
taintedArg = asSinkExpr(sinkNode.getNode()) and taintedArg = asSinkExpr(sinkNode.getNode()) and
fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and
cfg.hasFilteredFlowPath(sourceNode, sinkNode) and cfg.hasFlowPath(sourceNode, sinkNode) and
taintSource = asSourceExpr(sourceNode.getNode()) and taintSource = sourceNode.getNode()
isUserInput(taintSource, taintCause)
select taintedArg, sourceNode, sinkNode, select taintedArg, sourceNode, sinkNode,
"This argument to a file access function is derived from $@ and then passed to " + callChain + ".", "This argument to a file access function is derived from $@ and then passed to " + callChain + ".",
taintSource, "user input (" + taintCause + ")" taintSource, "user input (" + taintSource.getSourceType() + ")"

View File

@@ -116,10 +116,6 @@ class ImproperArrayIndexValidationConfig extends TaintTracking::Configuration {
} }
} }
/** Gets `str` where the first letter has been lowercased. */
bindingset[str]
string lowerFirst(string str) { result = str.prefix(1).toLowerCase() + str.suffix(1) }
from from
ImproperArrayIndexValidationConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink, ImproperArrayIndexValidationConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink,
string sourceType string sourceType
@@ -128,4 +124,4 @@ where
isFlowSource(source.getNode(), sourceType) isFlowSource(source.getNode(), sourceType)
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"An array indexing expression depends on $@ that might be outside the bounds of the array.", "An array indexing expression depends on $@ that might be outside the bounds of the array.",
source.getNode(), lowerFirst(sourceType) source.getNode(), sourceType

View File

@@ -19,7 +19,25 @@ import semmle.code.cpp.ir.dataflow.TaintTracking
import DataFlow::PathGraph import DataFlow::PathGraph
/** /**
* A taint flow configuration for flow from user input to a buffer write. * A buffer write into a sensitive expression.
*/
class SensitiveBufferWrite extends Expr instanceof BufferWrite::BufferWrite {
SensitiveBufferWrite() { super.getDest() instanceof SensitiveExpr }
/**
* Gets a data source of this operation.
*/
Expr getASource() { result = super.getASource() }
/**
* Gets the destination buffer of this operation.
*/
Expr getDest() { result = super.getDest() }
}
/**
* A taint flow configuration for flow from user input to a buffer write
* into a sensitive expression.
*/ */
class ToBufferConfiguration extends TaintTracking::Configuration { class ToBufferConfiguration extends TaintTracking::Configuration {
ToBufferConfiguration() { this = "ToBufferConfiguration" } ToBufferConfiguration() { this = "ToBufferConfiguration" }
@@ -31,18 +49,17 @@ class ToBufferConfiguration extends TaintTracking::Configuration {
} }
override predicate isSink(DataFlow::Node sink) { override predicate isSink(DataFlow::Node sink) {
exists(BufferWrite::BufferWrite w | w.getASource() = sink.asExpr()) exists(SensitiveBufferWrite w | w.getASource() = sink.asExpr())
} }
} }
from from
ToBufferConfiguration config, BufferWrite::BufferWrite w, DataFlow::PathNode sourceNode, ToBufferConfiguration config, SensitiveBufferWrite w, DataFlow::PathNode sourceNode,
DataFlow::PathNode sinkNode, FlowSource source, SensitiveExpr dest DataFlow::PathNode sinkNode, FlowSource source
where where
config.hasFlowPath(sourceNode, sinkNode) and config.hasFlowPath(sourceNode, sinkNode) and
sourceNode.getNode() = source and sourceNode.getNode() = source and
w.getASource() = sinkNode.getNode().asExpr() and w.getASource() = sinkNode.getNode().asExpr()
dest = w.getDest()
select w, sourceNode, sinkNode, select w, sourceNode, sinkNode,
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@.", source, "This write into buffer '" + w.getDest().toString() + "' may contain unencrypted data from $@.",
"user input (" + source.getSourceType() + ")" source, "user input (" + source.getSourceType() + ")"

View File

@@ -11,8 +11,20 @@ class LocalFlowSourceTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) { override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "local_source" and tag = "local_source" and
value = "" and exists(LocalFlowSource node, int n |
exists(LocalFlowSource node | n =
strictcount(LocalFlowSource otherNode |
node.getLocation().getStartLine() = otherNode.getLocation().getStartLine()
) and
(
n = 1 and value = ""
or
// If there is more than one node on this line
// we specify the location explicitly.
n > 1 and
value =
node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn()
) and
location = node.getLocation() and location = node.getLocation() and
element = node.toString() element = node.toString()
) )

View File

@@ -11,8 +11,20 @@ class RemoteFlowSourceTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) { override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "remote_source" and tag = "remote_source" and
value = "" and exists(RemoteFlowSource node, int n |
exists(RemoteFlowSource node | n =
strictcount(RemoteFlowSource otherNode |
node.getLocation().getStartLine() = otherNode.getLocation().getStartLine()
) and
(
n = 1 and value = ""
or
// If there is more than one node on this line
// we specify the location explicitly.
n > 1 and
value =
node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn()
) and
location = node.getLocation() and location = node.getLocation() and
element = node.toString() element = node.toString()
) )
@@ -26,8 +38,20 @@ class RemoteFlowSinkTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) { override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "remote_sink" and tag = "remote_sink" and
value = "" and exists(RemoteFlowSink node, int n |
exists(RemoteFlowSink node | n =
strictcount(RemoteFlowSink otherNode |
node.getLocation().getStartLine() = otherNode.getLocation().getStartLine()
) and
(
n = 1 and value = ""
or
// If there is more than one node on this line
// we specify the location explicitly.
n > 1 and
value =
node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn()
) and
location = node.getLocation() and location = node.getLocation() and
element = node.toString() element = node.toString()
) )

View File

@@ -26,3 +26,27 @@ void test_readv_and_writev(iovec* iovs) {
readv(0, iovs, 16); // $ remote_source readv(0, iovs, 16); // $ remote_source
writev(0, iovs, 16); // $ remote_sink writev(0, iovs, 16); // $ remote_sink
} }
struct FILE;
int fscanf(FILE *stream, const char *format, ...);
int scanf(const char *format, ...);
void test_scanf(FILE *stream, int *d, char *buf) {
scanf(""); // Not a local source, as there are no output arguments
fscanf(stream, ""); // Not a remote source, as there are no output arguments
scanf("%d", d); // $ local_source
fscanf(stream, "%d", d); // $ remote_source
scanf("%d %s", d, buf); // $ local_source=40:18 local_source=40:21
fscanf(stream, "%d %s", d, buf); // $ remote_source=41:27 remote_source=41:30
}
struct addrinfo;
int getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
void test_inet(char *hostname, char *servname, struct addrinfo *hints) {
addrinfo *res;
int ret = getaddrinfo(hostname, servname, hints, &res); // $ remote_source
}

View File

@@ -5,4 +5,4 @@ nodes
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection | | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
subpaths subpaths
#select #select
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | user input (fgets) | | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | user input (string read by fgets) |

View File

@@ -1,24 +1,20 @@
edges edges
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
| test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection |
| test.c:37:17:37:24 | fileName | test.c:38:11:38:18 | fileName indirection |
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
| test.c:43:17:43:24 | fileName | test.c:44:11:44:18 | fileName indirection |
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
nodes nodes
| test.c:9:23:9:26 | argv | semmle.label | argv | | test.c:9:23:9:26 | argv | semmle.label | argv |
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection | | test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:31:22:31:25 | argv | semmle.label | argv | | test.c:31:22:31:25 | argv | semmle.label | argv |
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection | | test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:37:17:37:24 | fileName | semmle.label | fileName |
| test.c:37:17:37:24 | scanf output argument | semmle.label | scanf output argument | | test.c:37:17:37:24 | scanf output argument | semmle.label | scanf output argument |
| test.c:38:11:38:18 | fileName indirection | semmle.label | fileName indirection | | test.c:38:11:38:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:43:17:43:24 | fileName | semmle.label | fileName |
| test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument | | test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument |
| test.c:44:11:44:18 | fileName indirection | semmle.label | fileName indirection | | test.c:44:11:44:18 | fileName indirection | semmle.label | fileName indirection |
subpaths subpaths
#select #select
| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (argv) | | test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (a command-line argument) |
| test.c:32:11:32:18 | fileName | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:31:22:31:25 | argv | user input (argv) | | test.c:32:11:32:18 | fileName | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:31:22:31:25 | argv | user input (a command-line argument) |
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | fileName | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | fileName | user input (scanf) | | test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | fileName | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | fileName | user input (scanf) | | test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |

View File

@@ -163,17 +163,17 @@ subpaths
#select #select
| test.cpp:23:12:23:19 | command1 | test.cpp:16:20:16:23 | argv | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:16:20:16:23 | argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument | | test.cpp:23:12:23:19 | command1 | test.cpp:16:20:16:23 | argv | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:16:20:16:23 | argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument | | test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (String read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument | | test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (String read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument | | test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (String read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument | | test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (string read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument |
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ | | test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | Call | Call | | test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | Call | Call |
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | Call | Call | | test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | Call | Call |
| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (String read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument | | test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (string read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument |
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument | | test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument |
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument | | test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument |
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument | | test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument |
| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (String read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument | | test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument |
| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (String read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument | | test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument |
| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (String read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | | test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument |
| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (String read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | | test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument |

View File

@@ -7,42 +7,12 @@ edges
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 |
| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 |
| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 |
| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
@@ -65,16 +35,11 @@ nodes
| tests.c:29:28:29:34 | access to array | semmle.label | access to array | | tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection | | tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection |
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument |
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:34:10:34:13 | argv | semmle.label | argv | | tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:13 | argv | semmle.label | argv | | tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... | | tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... |
@@ -84,11 +49,6 @@ nodes
#select #select
| tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | | tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | | tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 | | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:33:21:33:29 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:33:21:33:29 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 | | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 |
| tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv | | tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv |

View File

@@ -6,5 +6,5 @@ nodes
| test.cpp:58:25:58:29 | input | semmle.label | input | | test.cpp:58:25:58:29 | input | semmle.label | input |
subpaths subpaths
#select #select
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets | user input (String read by gets) | | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets | user input (string read by gets) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:54:17:54:20 | argv | user input (a command-line argument) | | test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:54:17:54:20 | argv | user input (a command-line argument) |

View File

@@ -15,7 +15,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Build" Version="17.3.2" /> <PackageReference Include="Microsoft.Build" Version="17.3.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj" /> <ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj" />

View File

@@ -10195,7 +10195,7 @@ extensions:
- addsTo: - addsTo:
pack: codeql/csharp-all pack: codeql/csharp-all
extensible: extNegativeSummaryModel extensible: extNeutralModel
data: data:
- ["AssemblyStripper", "AssemblyStripper", "StripAssembly", "(System.String,System.String)", "generated"] - ["AssemblyStripper", "AssemblyStripper", "StripAssembly", "(System.String,System.String)", "generated"]
- ["Generators", "EventSourceGenerator", "Execute", "(Microsoft.CodeAnalysis.GeneratorExecutionContext)", "generated"] - ["Generators", "EventSourceGenerator", "Execute", "(Microsoft.CodeAnalysis.GeneratorExecutionContext)", "generated"]

View File

@@ -368,40 +368,32 @@ private Stmt getAnAssertingStmt(Assertion a) {
} }
/** A method that forwards to a Boolean assertion method. */ /** A method that forwards to a Boolean assertion method. */
class ForwarderBooleanAssertMethod extends BooleanAssertMethod { class ForwarderBooleanAssertMethod extends BooleanAssertMethod instanceof ForwarderAssertMethod {
private ForwarderAssertMethod forwarder;
private BooleanAssertMethod underlying; private BooleanAssertMethod underlying;
ForwarderBooleanAssertMethod() { ForwarderBooleanAssertMethod() { underlying = super.getUnderlyingAssertMethod() }
forwarder = this and
underlying = forwarder.getUnderlyingAssertMethod()
}
override int getAnAssertionIndex(boolean b) { override int getAnAssertionIndex(boolean b) {
forwarder.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b) super.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b)
} }
override AssertionFailure getAssertionFailure(int i) { override AssertionFailure getAssertionFailure(int i) {
result = underlying.getAssertionFailure(forwarder.getAForwarderAssertionIndex(i)) result = underlying.getAssertionFailure(super.getAForwarderAssertionIndex(i))
} }
} }
/** A method that forwards to a nullness assertion method. */ /** A method that forwards to a nullness assertion method. */
class ForwarderNullnessAssertMethod extends NullnessAssertMethod { class ForwarderNullnessAssertMethod extends NullnessAssertMethod instanceof ForwarderAssertMethod {
private ForwarderAssertMethod forwarder;
private NullnessAssertMethod underlying; private NullnessAssertMethod underlying;
ForwarderNullnessAssertMethod() { ForwarderNullnessAssertMethod() { underlying = super.getUnderlyingAssertMethod() }
forwarder = this and
underlying = forwarder.getUnderlyingAssertMethod()
}
override int getAnAssertionIndex(boolean b) { override int getAnAssertionIndex(boolean b) {
forwarder.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b) super.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b)
} }
override AssertionFailure getAssertionFailure(int i) { override AssertionFailure getAssertionFailure(int i) {
result = underlying.getAssertionFailure(forwarder.getAForwarderAssertionIndex(i)) result = underlying.getAssertionFailure(super.getAForwarderAssertionIndex(i))
} }
} }

View File

@@ -11,9 +11,9 @@
* `namespace; type; subtypes; name; signature; ext; input; kind; provenance` * `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
* - Summaries: * - Summaries:
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance` * `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
* - Negative Summaries: * - Neutrals:
* `namespace; type; name; signature; provenance` * `namespace; type; name; signature; provenance`
* A negative summary is used to indicate that there is no flow via a callable. * A neutral is used to indicate that there is no flow via a callable.
* *
* The interpretation of a row is similar to API-graphs with a left-to-right * The interpretation of a row is similar to API-graphs with a left-to-right
* reading. * reading.
@@ -132,30 +132,12 @@ private class SummaryModelCsvInternal extends Unit {
abstract predicate row(string row); abstract predicate row(string row);
} }
/**
* DEPRECATED: Define negative summary models as data extensions instead.
*
* A unit class for adding additional negative summary model rows.
*
* Extend this class to add additional negative summary definitions.
*/
deprecated class NegativeSummaryModelCsv = NegativeSummaryModelCsvInternal;
private class NegativeSummaryModelCsvInternal extends Unit {
/** Holds if `row` specifies a negative summary definition. */
abstract predicate row(string row);
}
private predicate sourceModelInternal(string row) { any(SourceModelCsvInternal s).row(row) } private predicate sourceModelInternal(string row) { any(SourceModelCsvInternal s).row(row) }
private predicate summaryModelInternal(string row) { any(SummaryModelCsvInternal s).row(row) } private predicate summaryModelInternal(string row) { any(SummaryModelCsvInternal s).row(row) }
private predicate sinkModelInternal(string row) { any(SinkModelCsvInternal s).row(row) } private predicate sinkModelInternal(string row) { any(SinkModelCsvInternal s).row(row) }
private predicate negativeSummaryModelInternal(string row) {
any(NegativeSummaryModelCsvInternal s).row(row)
}
/** /**
* Holds if a source model exists for the given parameters. * Holds if a source model exists for the given parameters.
*/ */
@@ -243,25 +225,16 @@ predicate summaryModel(
extSummaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) extSummaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance)
} }
/** Holds if a summary model exists indicating there is no flow for the given parameters. */ /** Holds if a model exists indicating there is no flow for the given parameters. */
extensible predicate extNegativeSummaryModel( extensible predicate extNeutralModel(
string namespace, string type, string name, string signature, string provenance string namespace, string type, string name, string signature, string provenance
); );
/** Holds if a summary model exists indicating there is no flow for the given parameters. */ /** Holds if a model exists indicating there is no flow for the given parameters. */
predicate negativeSummaryModel( predicate neutralModel(
string namespace, string type, string name, string signature, string provenance string namespace, string type, string name, string signature, string provenance
) { ) {
exists(string row | extNeutralModel(namespace, type, name, signature, provenance)
negativeSummaryModelInternal(row) and
row.splitAt(";", 0) = namespace and
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = name and
row.splitAt(";", 3) = signature and
row.splitAt(";", 4) = provenance
)
or
extNegativeSummaryModel(namespace, type, name, signature, provenance)
} }
private predicate relevantNamespace(string namespace) { private predicate relevantNamespace(string namespace) {
@@ -393,8 +366,6 @@ module ModelValidation {
sinkModelInternal(row) and expect = 9 and pred = "sink" sinkModelInternal(row) and expect = 9 and pred = "sink"
or or
summaryModelInternal(row) and expect = 10 and pred = "summary" summaryModelInternal(row) and expect = 10 and pred = "summary"
or
negativeSummaryModelInternal(row) and expect = 5 and pred = "negative summary"
| |
exists(int cols | exists(int cols |
cols = 1 + max(int n | exists(row.splitAt(";", n))) and cols = 1 + max(int n | exists(row.splitAt(";", n))) and
@@ -418,9 +389,9 @@ module ModelValidation {
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
pred = "summary" pred = "summary"
or or
negativeSummaryModel(namespace, type, name, signature, provenance) and neutralModel(namespace, type, name, signature, provenance) and
ext = "" and ext = "" and
pred = "negative summary" pred = "neutral"
| |
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
result = "Dubious namespace \"" + namespace + "\" in " + pred + " model." result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
@@ -461,7 +432,7 @@ private predicate elementSpec(
or or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
or or
negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false neutralModel(namespace, type, name, signature, _) and ext = "" and subtypes = false
} }
private predicate elementSpec( private predicate elementSpec(
@@ -595,7 +566,7 @@ private Element interpretElement0(
) )
} }
/** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */ /** Gets the source/sink/summary/neutral element corresponding to the supplied parameters. */
Element interpretElement( Element interpretElement(
string namespace, string type, boolean subtypes, string name, string signature, string ext string namespace, string type, boolean subtypes, string name, string signature, string ext
) { ) {

View File

@@ -222,18 +222,14 @@ module ContentDataFlow {
) )
} }
private class ConfigurationAdapter extends DF::Configuration { private class ConfigurationAdapter extends DF::Configuration instanceof Configuration {
private Configuration c;
ConfigurationAdapter() { this = c }
final override predicate isSource(Node source, DF::FlowState state) { final override predicate isSource(Node source, DF::FlowState state) {
c.isSource(source) and Configuration.super.isSource(source) and
state.(InitState).decode(true) state.(InitState).decode(true)
} }
final override predicate isSink(Node sink, DF::FlowState state) { final override predicate isSink(Node sink, DF::FlowState state) {
c.isSink(sink) and Configuration.super.isSink(sink) and
( (
state instanceof InitState or state instanceof InitState or
state instanceof StoreState or state instanceof StoreState or
@@ -249,9 +245,9 @@ module ContentDataFlow {
additionalStep(node1, state1, node2, state2, this) additionalStep(node1, state1, node2, state2, this)
} }
final override predicate isBarrier(Node node) { c.isBarrier(node) } final override predicate isBarrier(Node node) { Configuration.super.isBarrier(node) }
final override FlowFeature getAFeature() { result = c.getAFeature() } final override FlowFeature getAFeature() { result = Configuration.super.getAFeature() }
// needed to record reads/stores inside summarized callables // needed to record reads/stores inside summarized callables
final override predicate includeHiddenNodes() { any() } final override predicate includeHiddenNodes() { any() }

View File

@@ -2321,8 +2321,8 @@ module Csv {
) )
} }
/** Computes the first 4 columns for negative CSV rows of `c`. */ /** Computes the first 4 columns for neutral CSV rows of `c`. */
string asPartialNegativeModel(DotNet::Callable c) { string asPartialNeutralModel(DotNet::Callable c) {
exists(string namespace, string type, string name, string parameters | exists(string namespace, string type, string name, string parameters |
partialModel(c, namespace, type, name, parameters) and partialModel(c, namespace, type, name, parameters) and
result = result =

View File

@@ -246,14 +246,14 @@ module Public {
predicate isAutoGenerated() { none() } predicate isAutoGenerated() { none() }
} }
/** A callable with a flow summary stating there is no flow via the callable. */ /** A callable where there is no flow via the callable. */
class NegativeSummarizedCallable extends SummarizedCallableBase { class NeutralCallable extends SummarizedCallableBase {
NegativeSummarizedCallable() { negativeSummaryElement(this, _) } NeutralCallable() { neutralElement(this, _) }
/** /**
* Holds if the negative summary is auto generated. * Holds if the neutral is auto generated.
*/ */
predicate isAutoGenerated() { negativeSummaryElement(this, true) } predicate isAutoGenerated() { neutralElement(this, true) }
} }
} }
@@ -1161,9 +1161,9 @@ module Private {
string toString() { result = super.toString() } string toString() { result = super.toString() }
} }
/** A flow summary to include in the `negativeSummary/1` query predicate. */ /** A model to include in the `neutral/1` query predicate. */
abstract class RelevantNegativeSummarizedCallable instanceof NegativeSummarizedCallable { abstract class RelevantNeutralCallable instanceof NeutralCallable {
/** Gets the string representation of this callable used by `summary/1`. */ /** Gets the string representation of this callable used by `neutral/1`. */
abstract string getCallableCsv(); abstract string getCallableCsv();
string toString() { result = super.toString() } string toString() { result = super.toString() }
@@ -1180,13 +1180,13 @@ module Private {
if c.isAutoGenerated() then result = "generated" else result = "manual" if c.isAutoGenerated() then result = "generated" else result = "manual"
} }
private string renderProvenanceNegative(NegativeSummarizedCallable c) { private string renderProvenanceNeutral(NeutralCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual" if c.isAutoGenerated() then result = "generated" else result = "manual"
} }
/** /**
* A query predicate for outputting flow summaries in semi-colon separated format in QL tests. * A query predicate for outputting flow summaries in semi-colon separated format in QL tests.
* The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance"", * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance",
* ext is hardcoded to empty. * ext is hardcoded to empty.
*/ */
query predicate summary(string csv) { query predicate summary(string csv) {
@@ -1205,14 +1205,14 @@ module Private {
} }
/** /**
* Holds if a negative flow summary `csv` exists (semi-colon separated format). Used for testing purposes. * Holds if a neutral model `csv` exists (semi-colon separated format). Used for testing purposes.
* The syntax is: "namespace;type;name;signature;provenance"", * The syntax is: "namespace;type;name;signature;provenance"",
*/ */
query predicate negativeSummary(string csv) { query predicate neutral(string csv) {
exists(RelevantNegativeSummarizedCallable c | exists(RelevantNeutralCallable c |
csv = csv =
c.getCallableCsv() // Callable information c.getCallableCsv() // Callable information
+ renderProvenanceNegative(c) // provenance + renderProvenanceNeutral(c) // provenance
) )
} }
} }

View File

@@ -121,12 +121,12 @@ predicate summaryElement(Callable c, string input, string output, string kind, b
} }
/** /**
* Holds if a negative flow summary exists for `c`, which means that there is no * Holds if a neutral model exists for `c`, which means that there is no
* flow through `c`. The flag `generated` states whether the summary is autogenerated. * flow through `c`. The flag `generated` states whether the neutral model is autogenerated.
*/ */
predicate negativeSummaryElement(Callable c, boolean generated) { predicate neutralElement(Callable c, boolean generated) {
exists(string namespace, string type, string name, string signature, string provenance | exists(string namespace, string type, string name, string signature, string provenance |
negativeSummaryModel(namespace, type, name, signature, provenance) and neutralModel(namespace, type, name, signature, provenance) and
generated = isGenerated(provenance) and generated = isGenerated(provenance) and
c = interpretElement(namespace, type, false, name, signature, "") c = interpretElement(namespace, type, false, name, signature, "")
) )

View File

@@ -257,9 +257,7 @@ class SystemNullReferenceExceptionClass extends SystemClass {
} }
/** The `System.Object` class. */ /** The `System.Object` class. */
class SystemObjectClass extends SystemClass { class SystemObjectClass extends SystemClass instanceof ObjectType {
SystemObjectClass() { this instanceof ObjectType }
/** Gets the `Equals(object)` method. */ /** Gets the `Equals(object)` method. */
Method getEqualsMethod() { Method getEqualsMethod() {
result.getDeclaringType() = this and result.getDeclaringType() = this and

View File

@@ -56,6 +56,4 @@ class ProtectSanitizer extends Sanitizer {
/** /**
* An external location sink. * An external location sink.
*/ */
class ExternalSink extends Sink { class ExternalSink extends Sink instanceof ExternalLocationSink { }
ExternalSink() { this instanceof ExternalLocationSink }
}

View File

@@ -38,14 +38,10 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** A source of local user input. */ /** A source of local user input. */
class LocalSource extends Source { class LocalSource extends Source instanceof LocalFlowSource { }
LocalSource() { this instanceof LocalFlowSource }
}
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }

View File

@@ -36,9 +36,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* A sink in `System.Diagnostic.Process` or its related classes. * A sink in `System.Diagnostic.Process` or its related classes.

View File

@@ -43,9 +43,7 @@ class Configuration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** The result of a reverse dns may be user-controlled. */ /** The result of a reverse dns may be user-controlled. */
class ReverseDnsSource extends Source { class ReverseDnsSource extends Source {

View File

@@ -39,6 +39,4 @@ private class PrivateDataSource extends Source {
PrivateDataSource() { this.getExpr() instanceof PrivateDataExpr } PrivateDataSource() { this.getExpr() instanceof PrivateDataExpr }
} }
private class ExternalLocation extends Sink { private class ExternalLocation extends Sink instanceof ExternalLocationSink { }
ExternalLocation() { this instanceof ExternalLocationSink }
}

View File

@@ -17,8 +17,7 @@ abstract class SafeExternalApiCallable extends Callable { }
/** DEPRECATED: Alias for SafeExternalApiCallable */ /** DEPRECATED: Alias for SafeExternalApiCallable */
deprecated class SafeExternalAPICallable = SafeExternalApiCallable; deprecated class SafeExternalAPICallable = SafeExternalApiCallable;
private class SummarizedCallableSafe extends SafeExternalApiCallable { private class SummarizedCallableSafe extends SafeExternalApiCallable instanceof SummarizedCallable {
SummarizedCallableSafe() { this instanceof SummarizedCallable }
} }
/** The default set of "safe" external APIs. */ /** The default set of "safe" external APIs. */

View File

@@ -38,9 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* An argument that sets the `Path` property of a `DirectoryEntry` object that is a sink for LDAP * An argument that sets the `Path` property of a `DirectoryEntry` object that is a sink for LDAP

View File

@@ -38,9 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
private class RemoteSource extends Source { private class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
private class HtmlSanitizer extends Sanitizer { private class HtmlSanitizer extends Sanitizer {
HtmlSanitizer() { this.asExpr() instanceof HtmlSanitizedExpr } HtmlSanitizer() { this.asExpr() instanceof HtmlSanitizedExpr }

View File

@@ -43,9 +43,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* The input argument to a call to `XmlReader.Create` where the input will not be validated against * The input argument to a call to `XmlReader.Create` where the input will not be validated against

View File

@@ -38,9 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* An expression that represents a regular expression with potential exponential behavior. * An expression that represents a regular expression with potential exponential behavior.

View File

@@ -37,9 +37,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* A `pattern` argument to a construction of a `Regex`. * A `pattern` argument to a construction of a `Regex`.

View File

@@ -37,14 +37,10 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** A source of local user input. */ /** A source of local user input. */
class LocalSource extends Source { class LocalSource extends Source instanceof LocalFlowSource { }
LocalSource() { this instanceof LocalFlowSource }
}
/** An argument to the `ConnectionString` property on a data connection class. */ /** An argument to the `ConnectionString` property on a data connection class. */
class SqlConnectionStringSink extends Sink { class SqlConnectionStringSink extends Sink {

View File

@@ -38,14 +38,10 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** A source of local user input. */ /** A source of local user input. */
class LocalSource extends Source { class LocalSource extends Source instanceof LocalFlowSource { }
LocalSource() { this instanceof LocalFlowSource }
}
/** An SQL expression passed to an API call that executes SQL. */ /** An SQL expression passed to an API call that executes SQL. */
class SqlInjectionExprSink extends Sink { class SqlInjectionExprSink extends Sink {

View File

@@ -39,9 +39,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* A path argument to a `File` method call. * A path argument to a `File` method call.

View File

@@ -44,9 +44,7 @@ abstract private class ConstructorOrStaticMethodSink extends Sink { }
*/ */
abstract class Sanitizer extends DataFlow::Node { } abstract class Sanitizer extends DataFlow::Node { }
private class RemoteSource extends Source { private class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* User input to object method call deserialization flow tracking. * User input to object method call deserialization flow tracking.

View File

@@ -50,9 +50,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* A URL argument to a call to `HttpResponse.Redirect()` or `Controller.Redirect()`, that is a * A URL argument to a call to `HttpResponse.Redirect()` or `Controller.Redirect()`, that is a

View File

@@ -14,9 +14,7 @@ private import semmle.code.csharp.security.Sanitizers
*/ */
abstract class Source extends DataFlow::Node { } abstract class Source extends DataFlow::Node { }
private class RemoteSource extends Source { private class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* A data flow sink for untrusted user input used in XML processing. * A data flow sink for untrusted user input used in XML processing.

View File

@@ -37,9 +37,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** The `xpath` argument to an `XPathExpression.Compile(..)` call. */ /** The `xpath` argument to an `XPathExpression.Compile(..)` call. */
class XPathExpressionCompileSink extends Sink { class XPathExpressionCompileSink extends Sink {

View File

@@ -149,9 +149,7 @@ class TaintTrackingConfiguration extends TaintTracking2::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
private class RemoteSource extends Source { private class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }

View File

@@ -27,9 +27,7 @@ private class ExternalXssSink extends Sink {
ExternalXssSink() { sinkNode(this, "xss") } ExternalXssSink() { sinkNode(this, "xss") }
} }
private class HtmlSinkSink extends Sink { private class HtmlSinkSink extends Sink instanceof HtmlSink {
HtmlSinkSink() { this instanceof HtmlSink }
override string explanation() { override string explanation() {
this instanceof WebPageWriteLiteralSink and this instanceof WebPageWriteLiteralSink and
result = "System.Web.WebPages.WebPage.WriteLiteral() method" result = "System.Web.WebPages.WebPage.WriteLiteral() method"

View File

@@ -44,9 +44,7 @@ class SuppressionComment extends CommentLine {
/** /**
* The scope of an alert suppression comment. * The scope of an alert suppression comment.
*/ */
class SuppressionScope extends @commentline { class SuppressionScope extends @commentline instanceof SuppressionComment {
SuppressionScope() { this instanceof SuppressionComment }
/** Gets a suppression comment with this scope. */ /** Gets a suppression comment with this scope. */
SuppressionComment getSuppressionComment() { result = this } SuppressionComment getSuppressionComment() { result = this }
@@ -60,7 +58,7 @@ class SuppressionScope extends @commentline {
predicate hasLocationInfo( predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
) { ) {
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn) super.covers(filepath, startline, startcolumn, endline, endcolumn)
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */

View File

@@ -12,8 +12,8 @@ private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSumma
private import ExternalApi private import ExternalApi
private predicate relevant(ExternalApi api) { private predicate relevant(ExternalApi api) {
api.isSupported() or api.isSupported() or
api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable api instanceof FlowSummaryImpl::Public::NeutralCallable
} }
from string info, int usages from string info, int usages

View File

@@ -13,7 +13,7 @@ private import ExternalApi
private predicate relevant(ExternalApi api) { private predicate relevant(ExternalApi api) {
not api.isSupported() and not api.isSupported() and
not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable not api instanceof FlowSummaryImpl::Public::NeutralCallable
} }
from string info, int usages from string info, int usages

View File

@@ -51,9 +51,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
} }
/** A source of remote user input. */ /** A source of remote user input. */
class RemoteSource extends Source { class RemoteSource extends Source instanceof RemoteFlowSource { }
RemoteSource() { this instanceof RemoteFlowSource }
}
/** /**
* A path argument to a `WebClient` method call that has an address argument. * A path argument to a `WebClient` method call that has an address argument.

View File

@@ -58,9 +58,7 @@ module RequestForgery {
* A remote data flow source taken as a source * A remote data flow source taken as a source
* for Server Side Request Forgery(SSRF) Vulnerabilities. * for Server Side Request Forgery(SSRF) Vulnerabilities.
*/ */
private class RemoteFlowSourceAsSource extends Source { private class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
}
/** /**
* An url argument to a `HttpRequestMessage` constructor call * An url argument to a `HttpRequestMessage` constructor call

View File

@@ -17,5 +17,5 @@ from Call c, ExternalApi api
where where
c.getTarget().getUnboundDeclaration() = api and c.getTarget().getUnboundDeclaration() = api and
not api.isSupported() and not api.isSupported() and
not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable not api instanceof FlowSummaryImpl::Public::NeutralCallable
select c, "Call to unsupported external API $@.", api, api.toString() select c, "Call to unsupported external API $@.", api, api.toString()

View File

@@ -1,8 +1,8 @@
/** /**
* @name Capture negative summary models. * @name Capture neutral models.
* @description Finds negative summary models to be used by other queries. * @description Finds neutral models to be used by other queries.
* @kind diagnostic * @kind diagnostic
* @id cs/utils/model-generator/negative-summary-models * @id cs/utils/model-generator/neutral-models
* @tags model-generator * @tags model-generator
*/ */

View File

@@ -1,7 +1,7 @@
/** /**
* @name Extract MaD negative summary model rows. * @name Extract MaD neutral model rows.
* @description This extracts the Models as data negative summary model rows. * @description This extracts the Models as data neutral model rows.
* @id csharp/utils/modelconverter/generate-data-extensions-negative-summary * @id csharp/utils/modelconverter/generate-data-extensions-neutral
*/ */
import csharp import csharp
@@ -9,6 +9,6 @@ import semmle.code.csharp.dataflow.ExternalFlow
from string package, string type, string name, string signature, string provenance from string package, string type, string name, string signature, string provenance
where where
negativeSummaryModel(package, type, name, signature, provenance) and neutralModel(package, type, name, signature, provenance) and
provenance != "generated" provenance != "generated"
select package, type, name, signature, provenance order by package, type, name, signature select package, type, name, signature, provenance order by package, type, name, signature

View File

@@ -58,9 +58,7 @@ private string asSummaryModel(TargetApiSpecific api, string input, string output
+ "generated" + "generated"
} }
string asNegativeSummaryModel(TargetApiSpecific api) { string asNeutralModel(TargetApiSpecific api) { result = asPartialNeutralModel(api) + "generated" }
result = asPartialNegativeModel(api) + "generated"
}
/** /**
* Gets the value summary model for `api` with `input` and `output`. * Gets the value summary model for `api` with `input` and `output`.

View File

@@ -68,7 +68,7 @@ class TargetApiSpecific extends DotNet::Callable {
predicate asPartialModel = DataFlowPrivate::Csv::asPartialModel/1; predicate asPartialModel = DataFlowPrivate::Csv::asPartialModel/1;
predicate asPartialNegativeModel = DataFlowPrivate::Csv::asPartialNegativeModel/1; predicate asPartialNeutralModel = DataFlowPrivate::Csv::asPartialNeutralModel/1;
/** /**
* Holds if `t` is a type that is generally used for bulk data in collection types. * Holds if `t` is a type that is generally used for bulk data in collection types.

View File

@@ -85,10 +85,10 @@ string captureFlow(DataFlowTargetApi api) {
} }
/** /**
* Gets the negative summary for `api`, if any. * Gets the neutral model for `api`, if any.
* A negative summary is generated, if there does not exist any positive flow. * A neutral model is generated, if there does not exist summary model.
*/ */
string captureNoFlow(DataFlowTargetApi api) { string captureNoFlow(DataFlowTargetApi api) {
not exists(captureFlow(api)) and not exists(captureFlow(api)) and
result = asNegativeSummaryModel(api) result = asNeutralModel(api)
} }

View File

@@ -1,14 +1,10 @@
import csharp import csharp
import Common import Common
class TTConfig extends TaintTracking::Configuration { class TTConfig extends TaintTracking::Configuration instanceof Config {
Config c; override predicate isSource(DataFlow::Node source) { Config.super.isSource(source) }
TTConfig() { this = c } override predicate isSink(DataFlow::Node sink) { Config.super.isSink(sink) }
override predicate isSource(DataFlow::Node source) { c.isSource(source) }
override predicate isSink(DataFlow::Node sink) { c.isSink(sink) }
} }
from TTConfig c, DataFlow::Node source, DataFlow::Node sink from TTConfig c, DataFlow::Node source, DataFlow::Node sink

View File

@@ -6,14 +6,10 @@ import csharp
import Common import Common
import DataFlow::PathGraph import DataFlow::PathGraph
class TTConfig extends TaintTracking::Configuration { class TTConfig extends TaintTracking::Configuration instanceof Config {
Config c; override predicate isSource(DataFlow::Node source) { Config.super.isSource(source) }
TTConfig() { this = c } override predicate isSink(DataFlow::Node sink) { Config.super.isSink(sink) }
override predicate isSource(DataFlow::Node source) { c.isSource(source) }
override predicate isSink(DataFlow::Node sink) { c.isSink(sink) }
} }
from TTConfig c, DataFlow::PathNode source, DataFlow::PathNode sink, string s from TTConfig c, DataFlow::PathNode source, DataFlow::PathNode sink, string s

View File

@@ -11928,7 +11928,7 @@ summary
| System;ValueTuple<>;false;ToString;();;Argument[this];ReturnValue;taint;generated | | System;ValueTuple<>;false;ToString;();;Argument[this];ReturnValue;taint;generated |
| System;ValueTuple<>;false;ValueTuple;(T1);;Argument[0];Argument[this].Field[System.ValueTuple<>.Item1];value;manual | | System;ValueTuple<>;false;ValueTuple;(T1);;Argument[0];Argument[this].Field[System.ValueTuple<>.Item1];value;manual |
| System;ValueTuple<>;false;get_Item;(System.Int32);;Argument[this].Field[System.ValueTuple<>.Item1];ReturnValue;value;manual | | System;ValueTuple<>;false;get_Item;(System.Int32);;Argument[this].Field[System.ValueTuple<>.Item1];ReturnValue;value;manual |
negativeSummary neutral
| Microsoft.CSharp.RuntimeBinder;CSharpArgumentInfo;Create;(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,System.String);generated | | Microsoft.CSharp.RuntimeBinder;CSharpArgumentInfo;Create;(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,System.String);generated |
| Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;();generated | | Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;();generated |
| Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);generated | | Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);generated |

View File

@@ -6,11 +6,7 @@ private class IncludeAllSummarizedCallable extends IncludeSummarizedCallable {
IncludeAllSummarizedCallable() { exists(this) } IncludeAllSummarizedCallable() { exists(this) }
} }
private class IncludeNegativeSummarizedCallable extends RelevantNegativeSummarizedCallable { private class IncludeNeutralCallable extends RelevantNeutralCallable instanceof FlowSummaryImpl::Public::NeutralCallable {
IncludeNegativeSummarizedCallable() {
this instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable
}
/** Gets a string representing the callable in semi-colon separated format for use in flow summaries. */ /** Gets a string representing the callable in semi-colon separated format for use in flow summaries. */
final override string getCallableCsv() { result = Csv::asPartialNegativeModel(this) } final override string getCallableCsv() { result = Csv::asPartialNeutralModel(this) }
} }

View File

@@ -10262,4 +10262,4 @@ summary
| System;ValueTuple<>;false;ToString;();;Argument[this];ReturnValue;taint;generated | | System;ValueTuple<>;false;ToString;();;Argument[this];ReturnValue;taint;generated |
| System;ValueTuple<>;false;ValueTuple;(T1);;Argument[0];Argument[this].Field[System.ValueTuple<>.Item1];value;manual | | System;ValueTuple<>;false;ValueTuple;(T1);;Argument[0];Argument[this].Field[System.ValueTuple<>.Item1];value;manual |
| System;ValueTuple<>;false;get_Item;(System.Int32);;Argument[this].Field[System.ValueTuple<>.Item1];ReturnValue;value;manual | | System;ValueTuple<>;false;get_Item;(System.Int32);;Argument[this].Field[System.ValueTuple<>.Item1];ReturnValue;value;manual |
negativeSummary neutral

View File

@@ -2,9 +2,7 @@ import shared.FlowSummaries
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate::Csv private import semmle.code.csharp.dataflow.internal.DataFlowPrivate::Csv
private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.ExternalFlow
class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable { class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable instanceof SummarizedCallable {
IncludeFilteredSummarizedCallable() { this instanceof SummarizedCallable }
/** /**
* Holds if flow is propagated between `input` and `output` and * Holds if flow is propagated between `input` and `output` and
* if there is no summary for a callable in a `base` class or interface * if there is no summary for a callable in a `base` class or interface
@@ -13,7 +11,7 @@ class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
override predicate relevantSummary( override predicate relevantSummary(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) { ) {
this.(SummarizedCallable).propagatesFlow(input, output, preservesValue) and super.propagatesFlow(input, output, preservesValue) and
not exists(IncludeSummarizedCallable rsc | not exists(IncludeSummarizedCallable rsc |
isBaseCallableOrPrototype(rsc) and isBaseCallableOrPrototype(rsc) and
rsc.(SummarizedCallable).propagatesFlow(input, output, preservesValue) and rsc.(SummarizedCallable).propagatesFlow(input, output, preservesValue) and

View File

@@ -131,7 +131,7 @@ summary
| System.Data.Entity;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual | | System.Data.Entity;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual |
| System.Data.Entity;DbSet<>;false;Update;(T);;Argument[0];Argument[this].Element;value;manual | | System.Data.Entity;DbSet<>;false;Update;(T);;Argument[0];Argument[this].Element;value;manual |
| System.Data.Entity;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual | | System.Data.Entity;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual |
negativeSummary neutral
sourceNode sourceNode
sinkNode sinkNode
| EntityFrameworkCore.cs:72:36:72:40 | "sql" | sql | | EntityFrameworkCore.cs:72:36:72:40 | "sql" | sql |

View File

@@ -2,8 +2,7 @@ import semmle.code.csharp.frameworks.EntityFramework::EntityFramework
import shared.FlowSummaries import shared.FlowSummaries
import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow
private class IncludeEFSummarizedCallable extends IncludeSummarizedCallable { private class IncludeEFSummarizedCallable extends IncludeSummarizedCallable instanceof EFSummarizedCallable {
IncludeEFSummarizedCallable() { this instanceof EFSummarizedCallable }
} }
query predicate sourceNode(DataFlow::Node node, string kind) { query predicate sourceNode(DataFlow::Node node, string kind) {

View File

@@ -1 +0,0 @@
utils/model-generator/CaptureNegativeSummaryModels.ql

View File

@@ -0,0 +1 @@
utils/model-generator/CaptureNeutralModels.ql

View File

@@ -42,9 +42,10 @@ For more information, see
Building and previewing the CodeQL documentation Building and previewing the CodeQL documentation
************************************************ ************************************************
To build and preview the documentation and training presentations locally, you need to To build and preview the documentation and training presentations locally, you need to
install Sphinx 1.7.9. More recent versions of Sphinx do not work with hieroglyph, install Sphinx 1.7.9 using Python 2 (for example: `pip install sphinx==1.7.9`).
the Sphinx extension that we use to generate HTML slides, as explained below. More recent versions of Sphinx do not work with hieroglyph,
the Sphinx extension that we use to generate HTML slides, as explained below.
For installation options, see https://github.com/sphinx-doc/sphinx. For installation options, see https://github.com/sphinx-doc/sphinx.

View File

@@ -5,4 +5,4 @@ where
a.getAnOperand() = v.getAnAccess() and a.getAnOperand() = v.getAnAccess() and
cmp.getAnOperand() = a and cmp.getAnOperand() = a and
cmp.getAnOperand() = v.getAnAccess() cmp.getAnOperand() = v.getAnAccess()
select cmp, "Overflow check." select cmp, "Overflow check."

View File

@@ -6,4 +6,4 @@ where
cmp.getAnOperand() = a and cmp.getAnOperand() = a and
cmp.getAnOperand() = v.getAnAccess() and cmp.getAnOperand() = v.getAnAccess() and
forall(Expr op | op = a.getAnOperand() | isSmall(op)) forall(Expr op | op = a.getAnOperand() | isSmall(op))
select cmp, "Bad overflow check." select cmp, "Bad overflow check."

View File

@@ -9,4 +9,4 @@ where
cmp.getAnOperand() = v.getAnAccess() and cmp.getAnOperand() = v.getAnAccess() and
forall(Expr op | op = a.getAnOperand() | isSmall(op)) and forall(Expr op | op = a.getAnOperand() | isSmall(op)) and
not isSmall(a.getExplicitlyConverted()) not isSmall(a.getExplicitlyConverted())
select cmp, "Bad overflow check" select cmp, "Bad overflow check"

View File

@@ -1,8 +1,9 @@
import cpp import cpp
from FunctionCall alloc, FunctionCall free, LocalScopeVariable v from FunctionCall alloc, FunctionCall free, LocalScopeVariable v
where allocationCall(alloc) where
and alloc = v.getAnAssignedValue() allocationCall(alloc) and
and freeCall(free, v.getAnAccess()) alloc = v.getAnAssignedValue() and
and alloc.getASuccessor+() = free freeCall(free, v.getAnAccess()) and
alloc.getASuccessor+() = free
select alloc, free select alloc, free

View File

@@ -1,8 +1,9 @@
import cpp import cpp
from FunctionCall free, LocalScopeVariable v, VariableAccess u from FunctionCall free, LocalScopeVariable v, VariableAccess u
where freeCall(free, v.getAnAccess()) where
and u = v.getAnAccess() freeCall(free, v.getAnAccess()) and
and u.isRValue() u = v.getAnAccess() and
and free.getASuccessor+() = u u.isRValue() and
select free, u free.getASuccessor+() = u
select free, u

View File

@@ -7,4 +7,4 @@ where
use = lv.getAnAccess() and use = lv.getAnAccess() and
use = def.getASuccessor+() use = def.getASuccessor+()
) )
select lv, def select lv, def

View File

@@ -7,4 +7,4 @@ predicate isReachable(BasicBlock bb) {
from BasicBlock bb from BasicBlock bb
where not isReachable(bb) where not isReachable(bb)
select bb select bb

View File

@@ -1,10 +1,10 @@
import cpp import cpp
from ExprCall c, PointerDereferenceExpr deref, VariableAccess va, from ExprCall c, PointerDereferenceExpr deref, VariableAccess va, Access fnacc
Access fnacc where
where c.getLocation().getFile().getBaseName() = "cjpeg.c" and c.getLocation().getFile().getBaseName() = "cjpeg.c" and
c.getLocation().getStartLine() = 640 and c.getLocation().getStartLine() = 640 and
deref = c.getExpr() and deref = c.getExpr() and
va = deref.getOperand() and va = deref.getOperand() and
fnacc = va.getTarget().getAnAssignedValue() fnacc = va.getTarget().getAnAssignedValue()
select c, fnacc.getTarget() select c, fnacc.getTarget()

View File

@@ -2,7 +2,8 @@ import cpp
import semmle.code.cpp.commons.Printf import semmle.code.cpp.commons.Printf
from Call c, FormattingFunction ff, Expr format from Call c, FormattingFunction ff, Expr format
where c.getTarget() = ff and where
format = c.getArgument(ff.getFormatParameterIndex()) and c.getTarget() = ff and
not format instanceof StringLiteral format = c.getArgument(ff.getFormatParameterIndex()) and
select format, "Non-constant format string." not format instanceof StringLiteral
select format, "Non-constant format string."

View File

@@ -5,8 +5,9 @@ import semmle.code.cpp.commons.Printf
class SourceNode extends DataFlow::Node { /* ... */ } class SourceNode extends DataFlow::Node { /* ... */ }
from FormattingFunction f, Call c, SourceNode src, DataFlow::Node arg from FormattingFunction f, Call c, SourceNode src, DataFlow::Node arg
where c.getTarget() = f and where
arg.asExpr() = c.getArgument(f.getFormatParameterIndex()) and c.getTarget() = f and
DataFlow::localFlow(src, arg) and arg.asExpr() = c.getArgument(f.getFormatParameterIndex()) and
not src.asExpr() instanceof StringLiteral DataFlow::localFlow(src, arg) and
not src.asExpr() instanceof StringLiteral
select arg, "Non-constant format string." select arg, "Non-constant format string."

View File

@@ -1,11 +1,9 @@
import cpp import cpp
class EmptyBlock extends Block { class EmptyBlock extends Block {
EmptyBlock() { EmptyBlock() { this.isEmpty() }
this.isEmpty()
}
} }
from IfStmt ifStmt from IfStmt ifStmt
where ifstmt.getThen() instanceof EmptyBlock where ifstmt.getThen() instanceof EmptyBlock
select ifstmt select ifstmt

View File

@@ -8,4 +8,4 @@ from IfStmt ifstmt
where where
ifstmt.getThen() instanceof EmptyBlock and ifstmt.getThen() instanceof EmptyBlock and
not exists(ifstmt.getElse()) not exists(ifstmt.getElse())
select ifstmt, "This if-statement is redundant." select ifstmt, "This if-statement is redundant."

View File

@@ -1,9 +1,7 @@
import cpp import cpp
predicate isEmpty(Block block) { predicate isEmpty(Block block) { block.isEmpty() }
block.isEmpty()
}
from IfStmt ifstmt from IfStmt ifstmt
where isEmpty(ifstmt.getThen()) where isEmpty(ifstmt.getThen())
select ifstmt, "This if-statement is redundant." select ifstmt, "This if-statement is redundant."

View File

@@ -1,7 +1,7 @@
import cpp import cpp
from IfStmt ifstmt, Block block from IfStmt ifstmt, Block block
where where
block = ifstmt.getThen() and block = ifstmt.getThen() and
block.isEmpty() block.isEmpty()
select ifstmt, "This if-statement is redundant." select ifstmt, "This if-statement is redundant."

View File

@@ -3,11 +3,12 @@ import semmle.code.cpp.dataflow.TaintTracking
class TaintedFormatConfig extends TaintTracking::Configuration { class TaintedFormatConfig extends TaintTracking::Configuration {
TaintedFormatConfig() { this = "TaintedFormatConfig" } TaintedFormatConfig() { this = "TaintedFormatConfig" }
override predicate isSource(DataFlow::Node source) { /* TBD */ } override predicate isSource(DataFlow::Node source) { /* TBD */ }
override predicate isSink(DataFlow::Node sink) { /* TBD */ } override predicate isSink(DataFlow::Node sink) { /* TBD */ }
} }
from TaintedFormatConfig cfg, DataFlow::Node source, DataFlow::Node sink from TaintedFormatConfig cfg, DataFlow::Node source, DataFlow::Node sink
where cfg.hasFlow(source, sink) where cfg.hasFlow(source, sink)
select sink, "This format string may be derived from a $@.", select sink, "This format string may be derived from a $@.", source, "user-controlled value"
source, "user-controlled value"

View File

@@ -8,4 +8,4 @@ where
TaintTracking::localTaint(source, sink) and TaintTracking::localTaint(source, sink) and
source.asExpr() = call and source.asExpr() = call and
sink.asExpr() = call.getArgument(1) sink.asExpr() = call.getArgument(1)
select call select call

View File

@@ -8,4 +8,4 @@ from MethodAccess ma
where where
ma.getMethod().getName().matches("sparql%Query") and ma.getMethod().getName().matches("sparql%Query") and
ma.getArgument(0) instanceof StringConcat ma.getArgument(0) instanceof StringConcat
select ma, "SPARQL query vulnerable to injection." select ma, "SPARQL query vulnerable to injection."

View File

@@ -5,4 +5,4 @@ from MethodAccess ma, StringConcat stringConcat
where where
ma.getMethod().getName().matches("sparql%Query") and ma.getMethod().getName().matches("sparql%Query") and
localFlow(exprNode(stringConcat), exprNode(ma.getArgument(0))) localFlow(exprNode(stringConcat), exprNode(ma.getArgument(0)))
select ma, "SPARQL query vulnerable to injection." select ma, "SPARQL query vulnerable to injection."

View File

@@ -1,12 +1,9 @@
import java import java
class EmptyBlock extends Block { class EmptyBlock extends Block {
EmptyBlock() { EmptyBlock() { this.getNumStmt() = 0 }
this.getNumStmt() = 0
}
} }
from IfStmt ifstmt from IfStmt ifstmt
where ifstmt.getThen() instanceof where ifstmt.getThen() instanceof EmptyBlock
EmptyBlock
select ifstmt select ifstmt

View File

@@ -8,4 +8,4 @@ from IfStmt ifstmt
where where
ifstmt.getThen() instanceof EmptyBlock and ifstmt.getThen() instanceof EmptyBlock and
not exists(ifstmt.getElse()) not exists(ifstmt.getElse())
select ifstmt, "This if-statement is redundant." select ifstmt, "This if-statement is redundant."

View File

@@ -1,9 +1,7 @@
import java import java
predicate isEmpty(Block block) { predicate isEmpty(Block block) { block.getNumStmt() = 0 }
block.getNumStmt() = 0
}
from IfStmt ifstmt from IfStmt ifstmt
where isEmpty(ifstmt.getThen()) where isEmpty(ifstmt.getThen())
select ifstmt select ifstmt

View File

@@ -4,4 +4,4 @@ from IfStmt ifstmt, Block block
where where
block = ifstmt.getThen() and block = ifstmt.getThen() and
block.getNumStmt() = 0 block.getNumStmt() = 0
select ifstmt, "This if-statement is redundant." select ifstmt, "This if-statement is redundant."

Some files were not shown because too many files have changed in this diff Show More