mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Merge branch 'main' into jcogs33/update-externalapi-charpredicate
This commit is contained in:
21
.github/workflows/check-query-ids.yml
vendored
Normal file
21
.github/workflows/check-query-ids.yml
vendored
Normal 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
|
||||||
1
.github/workflows/swift.yml
vendored
1
.github/workflows/swift.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The `getaddrinfo` function is now recognized as a flow source.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The `scanf` and `fscanf` functions and their variants are now recognized as flow sources.
|
||||||
@@ -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`.
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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) }
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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) }
|
||||||
|
|||||||
@@ -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()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() + ")"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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() + ")"
|
||||||
|
|||||||
@@ -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()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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) |
|
||||||
|
|||||||
@@ -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) |
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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) |
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -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() }
|
||||||
|
|||||||
@@ -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 =
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, "")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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 { }
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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`.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 { }
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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`.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
utils/model-generator/CaptureNegativeSummaryModels.ql
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
utils/model-generator/CaptureNeutralModels.ql
|
||||||
@@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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"
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user