mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge branch 'main' into smowton/admin/kotlin-2.2.0-support
This commit is contained in:
@@ -4,7 +4,9 @@ No user-facing changes.
|
||||
|
||||
## 0.4.7
|
||||
|
||||
No user-facing changes.
|
||||
### New Features
|
||||
|
||||
* CodeQL and Copilot Autofix support for GitHub Actions is now Generally Available.
|
||||
|
||||
## 0.4.6
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.4.7
|
||||
|
||||
No user-facing changes.
|
||||
### New Features
|
||||
|
||||
* CodeQL and Copilot Autofix support for GitHub Actions is now Generally Available.
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
|
||||
## 0.5.4
|
||||
|
||||
### New Features
|
||||
|
||||
* CodeQL and Copilot Autofix support for GitHub Actions is now Generally Available.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Alerts produced by the query `actions/missing-workflow-permissions` now include a minimal set of recommended permissions in the alert message, based on well-known actions seen within the workflow file.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
## 0.5.4
|
||||
|
||||
### New Features
|
||||
|
||||
* CodeQL and Copilot Autofix support for GitHub Actions is now Generally Available.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Alerts produced by the query `actions/missing-workflow-permissions` now include a minimal set of recommended permissions in the alert message, based on well-known actions seen within the workflow file.
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
[]
|
||||
- queries: .
|
||||
- apply: code-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "a.h"
|
||||
#define FOUR 4
|
||||
@@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
return ONE + FOUR;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#import "d.h"
|
||||
@@ -0,0 +1,3 @@
|
||||
int main() {
|
||||
return SEVENTEEN;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#if 1
|
||||
#pragma hdrstop
|
||||
extern int x;
|
||||
#define SEEN_F
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifdef SEEN_F
|
||||
static int g() {
|
||||
return 20;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "h1.h"
|
||||
#pragma hdrstop
|
||||
#include "h2.h"
|
||||
#define SEEN_H
|
||||
@@ -13,4 +13,3 @@ static int h2() {
|
||||
return 32;
|
||||
}
|
||||
#endif
|
||||
// semmle-extractor-options: --clang -include-pch ${testdir}/clang-pch.testproj/h.pch
|
||||
@@ -0,0 +1,17 @@
|
||||
import os
|
||||
|
||||
|
||||
def test(codeql, cpp):
|
||||
os.mkdir("pch")
|
||||
extractor = cpp.get_tool("extractor")
|
||||
codeql.database.create(command=[
|
||||
f'"{extractor}" --mimic-clang -emit-pch -o pch/a.pch a.c',
|
||||
f'"{extractor}" --mimic-clang -include-pch pch/a.pch -Iextra_dummy_path b.c',
|
||||
f'"{extractor}" --mimic-clang -include pch/a -Iextra_dummy_path c.c',
|
||||
f'"{extractor}" --mimic-clang -emit-pch -o pch/d.pch d.c',
|
||||
f'"{extractor}" --mimic-clang -include-pch pch/d.pch e.c',
|
||||
f'"{extractor}" --mimic-clang -emit-pch -o pch/f.pch f.c',
|
||||
f'"{extractor}" --mimic-clang -include-pch pch/f.pch g.c',
|
||||
f'"{extractor}" --mimic-clang -emit-pch -o pch/h.pch h.c',
|
||||
f'"{extractor}" --mimic-clang -include-pch pch/h.pch i.c',
|
||||
])
|
||||
@@ -0,0 +1 @@
|
||||
#include "a.h"
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma hdrstop
|
||||
#include "b.h"
|
||||
|
||||
int b() {
|
||||
return A;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "d.h"
|
||||
#include "c.h"
|
||||
|
||||
int c() {
|
||||
return A;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import os
|
||||
|
||||
|
||||
def test(codeql, cpp):
|
||||
os.mkdir("pch")
|
||||
extractor = cpp.get_tool("extractor")
|
||||
codeql.database.create(command=[
|
||||
f'"{extractor}" --mimic-cl /Yca.h /Fppch/a.pch a.c',
|
||||
f'"{extractor}" --mimic-cl /Yub.h /Fppch/a.pch b.c',
|
||||
f'"{extractor}" --mimic-cl /Yuc.h /Fppch/a.pch c.c',
|
||||
])
|
||||
@@ -31,4 +31,6 @@ module CppDataFlow implements InputSig<Location> {
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
|
||||
predicate neverSkipInPathGraph = Private::neverSkipInPathGraph/1;
|
||||
|
||||
int defaultFieldFlowBranchLimit() { result = 3 }
|
||||
}
|
||||
|
||||
@@ -1652,8 +1652,6 @@ predicate validParameterAliasStep(Node node1, Node node2) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isTopLevel(Cpp::Stmt s) { any(Function f).getBlock().getAStmt() = s }
|
||||
|
||||
private Cpp::Stmt getAChainedBranch(Cpp::IfStmt s) {
|
||||
result = s.getThen()
|
||||
or
|
||||
@@ -1684,11 +1682,9 @@ private Instruction getAnInstruction(Node n) {
|
||||
}
|
||||
|
||||
private newtype TDataFlowSecondLevelScope =
|
||||
TTopLevelIfBranch(Cpp::Stmt s) {
|
||||
exists(Cpp::IfStmt ifstmt | s = getAChainedBranch(ifstmt) and isTopLevel(ifstmt))
|
||||
} or
|
||||
TTopLevelIfBranch(Cpp::Stmt s) { s = getAChainedBranch(_) } or
|
||||
TTopLevelSwitchCase(Cpp::SwitchCase s) {
|
||||
exists(Cpp::SwitchStmt switchstmt | s = switchstmt.getASwitchCase() and isTopLevel(switchstmt))
|
||||
exists(Cpp::SwitchStmt switchstmt | s = switchstmt.getASwitchCase())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,10 @@ module CastToPointerArithFlowConfig implements DataFlow::StateConfigSig {
|
||||
) and
|
||||
getFullyConvertedType(node) = state
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node node) { isSink(node, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @security-severity 7.8
|
||||
* @precision high
|
||||
* @tags security
|
||||
* external/cwe/cwe-14
|
||||
* external/cwe/cwe-014
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* to it.
|
||||
* @id cpp/count-untrusted-data-external-api
|
||||
* @kind table
|
||||
* @tags security external/cwe/cwe-20
|
||||
* @tags security external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* to it.
|
||||
* @id cpp/count-untrusted-data-external-api-ir
|
||||
* @kind table
|
||||
* @tags security external/cwe/cwe-20
|
||||
* @tags security external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @precision low
|
||||
* @problem.severity error
|
||||
* @security-severity 7.8
|
||||
* @tags security external/cwe/cwe-20
|
||||
* @tags security external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @precision low
|
||||
* @problem.severity error
|
||||
* @security-severity 7.8
|
||||
* @tags security external/cwe/cwe-20
|
||||
* @tags security external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
9
cpp/ql/src/change-notes/2025-05-01-cwe-tag-changed.md
Normal file
9
cpp/ql/src/change-notes/2025-05-01-cwe-tag-changed.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The tag `external/cwe/cwe-14` has been removed from `cpp/memset-may-be-deleted` and the tag `external/cwe/cwe-014` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cpp/count-untrusted-data-external-api` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cpp/count-untrusted-data-external-api-ir` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cpp/untrusted-data-to-external-api-ir` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cpp/untrusted-data-to-external-api` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cpp/late-check-of-function-argument` and the tag `external/cwe/cwe-020` has been added.
|
||||
@@ -1 +1,3 @@
|
||||
[]
|
||||
- queries: .
|
||||
- apply: code-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @tags correctness
|
||||
* security
|
||||
* experimental
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SummaryModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string flow
|
||||
where flow = ContentSensitive::captureFlow(api, _)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SummaryModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string noflow
|
||||
where noflow = captureNeutral(api)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import Heuristic
|
||||
import SinkModels
|
||||
|
||||
from DataFlowSinkTargetApi api, string sink
|
||||
where sink = captureSink(api)
|
||||
where sink = Heuristic::captureSink(api)
|
||||
select sink order by sink
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import Heuristic
|
||||
import SourceModels
|
||||
|
||||
from DataFlowSourceTargetApi api, string source
|
||||
where source = captureSource(api)
|
||||
where source = Heuristic::captureSource(api)
|
||||
select source order by source
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SummaryModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string flow
|
||||
where flow = captureFlow(api, _)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Provides predicates related to capturing summary models of the Standard or a 3rd party library.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import cpp as Cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.dataflow.ExternalFlow as ExternalFlow
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
|
||||
@@ -10,113 +10,67 @@ private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
private import semmle.code.cpp.dataflow.new.TaintTracking as Tt
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow as Df
|
||||
private import codeql.mad.modelgenerator.internal.ModelGeneratorImpl
|
||||
|
||||
module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFlow> {
|
||||
/**
|
||||
* Holds if `f` is a "private" function.
|
||||
*
|
||||
* A "private" function does not contribute any models as it is assumed
|
||||
* to be an implementation detail of some other "public" function for which
|
||||
* we will generate a summary.
|
||||
*/
|
||||
private predicate isPrivateOrProtected(Cpp::Function f) {
|
||||
f.getNamespace().getParentNamespace*().isAnonymous()
|
||||
or
|
||||
exists(Cpp::MemberFunction mf | mf = f |
|
||||
mf.isPrivate()
|
||||
or
|
||||
mf.isProtected()
|
||||
)
|
||||
or
|
||||
f.isStatic()
|
||||
}
|
||||
|
||||
private predicate isUninterestingForModels(Callable api) {
|
||||
// Note: This also makes all global/static-local variables
|
||||
// not relevant (which is good!)
|
||||
not api.(Cpp::Function).hasDefinition()
|
||||
or
|
||||
isPrivateOrProtected(api)
|
||||
or
|
||||
api instanceof Cpp::Destructor
|
||||
or
|
||||
api = any(Cpp::LambdaExpression lambda).getLambdaFunction()
|
||||
or
|
||||
api.isFromUninstantiatedTemplate(_)
|
||||
}
|
||||
|
||||
private predicate relevant(Callable api) {
|
||||
api.fromSource() and
|
||||
not isUninterestingForModels(api)
|
||||
}
|
||||
|
||||
module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Cpp::Location, CppDataFlow>
|
||||
{
|
||||
private module DataFlow = Df::DataFlow;
|
||||
|
||||
class Type = DataFlowPrivate::DataFlowType;
|
||||
|
||||
// Note: This also includes `this`
|
||||
class Parameter = DataFlow::ParameterNode;
|
||||
|
||||
class Callable = Declaration;
|
||||
class Callable = Cpp::Declaration;
|
||||
|
||||
class NodeExtended extends DataFlow::Node {
|
||||
Callable getAsExprEnclosingCallable() { result = this.asExpr().getEnclosingDeclaration() }
|
||||
}
|
||||
|
||||
Parameter asParameter(NodeExtended n) { result = n }
|
||||
|
||||
Callable getEnclosingCallable(NodeExtended n) {
|
||||
result = n.getEnclosingCallable().asSourceCallable()
|
||||
}
|
||||
|
||||
Callable getAsExprEnclosingCallable(NodeExtended n) {
|
||||
result = n.asExpr().getEnclosingDeclaration()
|
||||
}
|
||||
|
||||
/** Gets `api` if it is relevant. */
|
||||
private Callable liftedImpl(Callable api) { result = api and relevant(api) }
|
||||
|
||||
private predicate hasManualSummaryModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
private predicate hasManualSourceModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::NeutralSourceCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
private predicate hasManualSinkModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `f` is a "private" function.
|
||||
*
|
||||
* A "private" function does not contribute any models as it is assumed
|
||||
* to be an implementation detail of some other "public" function for which
|
||||
* we will generate a summary.
|
||||
*/
|
||||
private predicate isPrivateOrProtected(Function f) {
|
||||
f.getNamespace().getParentNamespace*().isAnonymous()
|
||||
or
|
||||
exists(MemberFunction mf | mf = f |
|
||||
mf.isPrivate()
|
||||
or
|
||||
mf.isProtected()
|
||||
)
|
||||
or
|
||||
f.isStatic()
|
||||
}
|
||||
|
||||
private predicate isUninterestingForModels(Callable api) {
|
||||
// Note: This also makes all global/static-local variables
|
||||
// not relevant (which is good!)
|
||||
not api.(Function).hasDefinition()
|
||||
or
|
||||
isPrivateOrProtected(api)
|
||||
or
|
||||
api instanceof Destructor
|
||||
or
|
||||
api = any(LambdaExpression lambda).getLambdaFunction()
|
||||
or
|
||||
api.isFromUninstantiatedTemplate(_)
|
||||
}
|
||||
|
||||
private predicate relevant(Callable api) {
|
||||
api.fromSource() and
|
||||
not isUninterestingForModels(api)
|
||||
}
|
||||
|
||||
class SummaryTargetApi extends Callable {
|
||||
private Callable lift;
|
||||
|
||||
SummaryTargetApi() {
|
||||
lift = liftedImpl(this) and
|
||||
not hasManualSummaryModel(lift)
|
||||
}
|
||||
|
||||
Callable lift() { result = lift }
|
||||
|
||||
predicate isRelevant() {
|
||||
relevant(this) and
|
||||
not hasManualSummaryModel(this)
|
||||
}
|
||||
}
|
||||
|
||||
class SourceOrSinkTargetApi extends Callable {
|
||||
SourceOrSinkTargetApi() { relevant(this) }
|
||||
}
|
||||
|
||||
class SinkTargetApi extends SourceOrSinkTargetApi {
|
||||
SinkTargetApi() { not hasManualSinkModel(this) }
|
||||
}
|
||||
|
||||
class SourceTargetApi extends SourceOrSinkTargetApi {
|
||||
SourceTargetApi() { not hasManualSourceModel(this) }
|
||||
}
|
||||
|
||||
class InstanceParameterNode extends DataFlow::ParameterNode {
|
||||
InstanceParameterNode() {
|
||||
DataFlowPrivate::nodeHasInstruction(this,
|
||||
@@ -124,7 +78,7 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
}
|
||||
}
|
||||
|
||||
private predicate isFinalMemberFunction(MemberFunction mf) {
|
||||
private predicate isFinalMemberFunction(Cpp::MemberFunction mf) {
|
||||
mf.isFinal()
|
||||
or
|
||||
mf.getDeclaringType().isFinal()
|
||||
@@ -146,12 +100,12 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
* - An uninstantiated template, or
|
||||
* - A declaration that is not from a template instantiation.
|
||||
*/
|
||||
private string templateParams(Declaration template) {
|
||||
private string templateParams(Cpp::Declaration template) {
|
||||
exists(string params |
|
||||
params =
|
||||
concat(int i |
|
||||
|
|
||||
template.getTemplateArgument(i).(TypeTemplateParameter).getName(), "," order by i
|
||||
template.getTemplateArgument(i).(Cpp::TypeTemplateParameter).getName(), "," order by i
|
||||
)
|
||||
|
|
||||
if params = "" then result = "" else result = "<" + params + ">"
|
||||
@@ -166,7 +120,7 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
* - An uninstantiated template, or
|
||||
* - A declaration that is not from a template instantiation.
|
||||
*/
|
||||
private string params(Function functionTemplate) {
|
||||
private string params(Cpp::Function functionTemplate) {
|
||||
exists(string params |
|
||||
params =
|
||||
concat(int i |
|
||||
@@ -193,7 +147,7 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
Callable callable, string namespace, string type, string name, string params
|
||||
) {
|
||||
exists(
|
||||
Function functionTemplate, string typeWithoutTemplateArgs, string nameWithoutTemplateArgs
|
||||
Cpp::Function functionTemplate, string typeWithoutTemplateArgs, string nameWithoutTemplateArgs
|
||||
|
|
||||
functionTemplate = ExternalFlow::getFullyTemplatedFunction(callable) and
|
||||
functionTemplate.hasQualifiedName(namespace, typeWithoutTemplateArgs, nameWithoutTemplateArgs) and
|
||||
@@ -201,7 +155,7 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
name = nameWithoutTemplateArgs + templateParams(functionTemplate) and
|
||||
params = params(functionTemplate)
|
||||
|
|
||||
exists(Class classTemplate |
|
||||
exists(Cpp::Class classTemplate |
|
||||
classTemplate = functionTemplate.getDeclaringType() and
|
||||
type = typeWithoutTemplateArgs + templateParams(classTemplate)
|
||||
)
|
||||
@@ -263,10 +217,10 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
|
||||
/** Holds if this instance access is to an enclosing instance of type `t`. */
|
||||
pragma[nomagic]
|
||||
private predicate isEnclosingInstanceAccess(DataFlowPrivate::ReturnNode n, Class t) {
|
||||
private predicate isEnclosingInstanceAccess(DataFlowPrivate::ReturnNode n, Cpp::Class t) {
|
||||
n.getKind().isIndirectReturn(-1) and
|
||||
t = n.getType().stripType() and
|
||||
t != n.getEnclosingCallable().asSourceCallable().(Function).getDeclaringType()
|
||||
t != n.getEnclosingCallable().asSourceCallable().(Cpp::Function).getDeclaringType()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -275,26 +229,6 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
not isEnclosingInstanceAccess(node, _)
|
||||
}
|
||||
|
||||
predicate sinkModelSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
predicate apiSource(DataFlow::Node source) {
|
||||
DataFlowPrivate::nodeHasOperand(source, any(DataFlow::FieldAddress fa), 1)
|
||||
or
|
||||
source instanceof DataFlow::ParameterNode
|
||||
}
|
||||
|
||||
string getInputArgument(DataFlow::Node source) {
|
||||
exists(DataFlowPrivate::Position pos, int argumentIndex, int indirectionIndex |
|
||||
source.(DataFlow::ParameterNode).isParameterOf(_, pos) and
|
||||
argumentIndex = pos.getArgumentIndex() and
|
||||
indirectionIndex = pos.getIndirectionIndex() and
|
||||
result = "Argument[" + DataFlow::repeatStars(indirectionIndex) + argumentIndex + "]"
|
||||
)
|
||||
or
|
||||
DataFlowPrivate::nodeHasOperand(source, any(DataFlow::FieldAddress fa), 1) and
|
||||
result = qualifierString()
|
||||
}
|
||||
|
||||
DataFlowPrivate::ParameterPosition getReturnKindParamPosition(DataFlowPrivate::ReturnKind k) {
|
||||
exists(int argumentIndex, int indirectionIndex |
|
||||
k.isIndirectReturn(argumentIndex) and
|
||||
@@ -314,18 +248,71 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
)
|
||||
}
|
||||
|
||||
predicate irrelevantSourceSinkApi(Callable source, SourceTargetApi api) { none() }
|
||||
|
||||
bindingset[kind]
|
||||
predicate isRelevantSourceKind(string kind) { any() }
|
||||
|
||||
bindingset[kind]
|
||||
predicate isRelevantSinkKind(string kind) { any() }
|
||||
|
||||
predicate containerContent(DataFlow::ContentSet cs) { cs instanceof DataFlow::ElementContent }
|
||||
|
||||
string partialModelRow(Callable api, int i) {
|
||||
i = 0 and qualifiedName(api, result, _, _, _) // namespace
|
||||
or
|
||||
i = 1 and qualifiedName(api, _, result, _, _) // type
|
||||
or
|
||||
i = 2 and result = isExtensible(api) // extensible
|
||||
or
|
||||
i = 3 and qualifiedName(api, _, _, result, _) // name
|
||||
or
|
||||
i = 4 and qualifiedName(api, _, _, _, result) // parameters
|
||||
or
|
||||
i = 5 and result = "" and exists(api) // ext
|
||||
}
|
||||
|
||||
string partialNeutralModelRow(Callable api, int i) {
|
||||
i = 0 and qualifiedName(api, result, _, _, _) // namespace
|
||||
or
|
||||
i = 1 and qualifiedName(api, _, result, _, _) // type
|
||||
or
|
||||
i = 2 and qualifiedName(api, _, _, result, _) // name
|
||||
or
|
||||
i = 3 and qualifiedName(api, _, _, _, result) // parameters
|
||||
}
|
||||
}
|
||||
|
||||
private import ModelGeneratorCommonInput
|
||||
private import MakeModelGeneratorFactory<Cpp::Location, CppDataFlow, CppTaintTracking, ModelGeneratorCommonInput>
|
||||
|
||||
private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
|
||||
private module DataFlow = Df::DataFlow;
|
||||
|
||||
Parameter asParameter(NodeExtended n) { result = n }
|
||||
|
||||
Callable getAsExprEnclosingCallable(NodeExtended n) {
|
||||
result = n.asExpr().getEnclosingDeclaration()
|
||||
}
|
||||
|
||||
private predicate hasManualSummaryModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
/** Gets `api` if it is relevant. */
|
||||
private Callable liftedImpl(Callable api) { result = api and relevant(api) }
|
||||
|
||||
class SummaryTargetApi extends Callable {
|
||||
private Callable lift;
|
||||
|
||||
SummaryTargetApi() {
|
||||
lift = liftedImpl(this) and
|
||||
not hasManualSummaryModel(lift)
|
||||
}
|
||||
|
||||
Callable lift() { result = lift }
|
||||
|
||||
predicate isRelevant() {
|
||||
relevant(this) and
|
||||
not hasManualSummaryModel(this)
|
||||
}
|
||||
}
|
||||
|
||||
predicate isAdditionalContentFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
TaintTracking::defaultAdditionalTaintStep(node1, node2, _) and
|
||||
Tt::TaintTracking::defaultAdditionalTaintStep(node1, node2, _) and
|
||||
not exists(DataFlow::Content f |
|
||||
DataFlowPrivate::readStep(node1, f, node2) and containerContent(f)
|
||||
)
|
||||
@@ -341,7 +328,7 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
predicate isCallback(DataFlow::ContentSet c) { none() }
|
||||
|
||||
string getSyntheticName(DataFlow::ContentSet c) {
|
||||
exists(Field f |
|
||||
exists(Cpp::Field f |
|
||||
not f.isPublic() and
|
||||
f = c.(DataFlow::FieldContent).getField() and
|
||||
result = f.getName()
|
||||
@@ -373,40 +360,52 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CppDataFl
|
||||
result = "Element[" + ec.getIndirectionIndex() + "]"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate isUninterestingForDataFlowModels(Callable api) { none() }
|
||||
|
||||
predicate isUninterestingForHeuristicDataFlowModels(Callable api) {
|
||||
isUninterestingForDataFlowModels(api)
|
||||
private module SourceModelGeneratorInput implements SourceModelGeneratorInputSig {
|
||||
private predicate hasManualSourceModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::NeutralSourceCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
string partialModelRow(Callable api, int i) {
|
||||
i = 0 and qualifiedName(api, result, _, _, _) // namespace
|
||||
or
|
||||
i = 1 and qualifiedName(api, _, result, _, _) // type
|
||||
or
|
||||
i = 2 and result = isExtensible(api) // extensible
|
||||
or
|
||||
i = 3 and qualifiedName(api, _, _, result, _) // name
|
||||
or
|
||||
i = 4 and qualifiedName(api, _, _, _, result) // parameters
|
||||
or
|
||||
i = 5 and result = "" and exists(api) // ext
|
||||
}
|
||||
|
||||
string partialNeutralModelRow(Callable api, int i) {
|
||||
i = 0 and qualifiedName(api, result, _, _, _) // namespace
|
||||
or
|
||||
i = 1 and qualifiedName(api, _, result, _, _) // type
|
||||
or
|
||||
i = 2 and qualifiedName(api, _, _, result, _) // name
|
||||
or
|
||||
i = 3 and qualifiedName(api, _, _, _, result) // parameters
|
||||
class SourceTargetApi extends Callable {
|
||||
SourceTargetApi() { relevant(this) and not hasManualSourceModel(this) }
|
||||
}
|
||||
|
||||
predicate sourceNode = ExternalFlow::sourceNode/2;
|
||||
}
|
||||
|
||||
private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
|
||||
private module DataFlow = Df::DataFlow;
|
||||
|
||||
private predicate hasManualSinkModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
class SinkTargetApi extends Callable {
|
||||
SinkTargetApi() { relevant(this) and not hasManualSinkModel(this) }
|
||||
}
|
||||
|
||||
predicate apiSource(DataFlow::Node source) {
|
||||
DataFlowPrivate::nodeHasOperand(source, any(DataFlow::FieldAddress fa), 1)
|
||||
or
|
||||
source instanceof DataFlow::ParameterNode
|
||||
}
|
||||
|
||||
string getInputArgument(DataFlow::Node source) {
|
||||
exists(DataFlowPrivate::Position pos, int argumentIndex, int indirectionIndex |
|
||||
source.(DataFlow::ParameterNode).isParameterOf(_, pos) and
|
||||
argumentIndex = pos.getArgumentIndex() and
|
||||
indirectionIndex = pos.getIndirectionIndex() and
|
||||
result = "Argument[" + DataFlow::repeatStars(indirectionIndex) + argumentIndex + "]"
|
||||
)
|
||||
or
|
||||
DataFlowPrivate::nodeHasOperand(source, any(DataFlow::FieldAddress fa), 1) and
|
||||
result = qualifierString()
|
||||
}
|
||||
|
||||
predicate sinkNode = ExternalFlow::sinkNode/2;
|
||||
}
|
||||
|
||||
import MakeModelGenerator<Location, CppDataFlow, CppTaintTracking, ModelGeneratorInput>
|
||||
import MakeSummaryModelGenerator<SummaryModelGeneratorInput> as SummaryModels
|
||||
import MakeSourceModelGenerator<SourceModelGeneratorInput> as SourceModels
|
||||
import MakeSinkModelGenerator<SinkModelGeneratorInput> as SinkModels
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import cpp as Cpp
|
||||
private import codeql.mad.modelgenerator.internal.ModelPrinting
|
||||
private import CaptureModels::ModelGeneratorInput as ModelGeneratorInput
|
||||
private import CaptureModels::ModelGeneratorCommonInput as ModelGeneratorInput
|
||||
|
||||
private module ModelPrintingLang implements ModelPrintingLangSig {
|
||||
class Callable = Cpp::Declaration;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// This file exists to ensure that the output subdirectory exists prior to
|
||||
// a.c being indexed, as said directory needs to exist for the PCH file to
|
||||
// be created, and will be created by running the extractor.
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "a.h"
|
||||
#define FOUR 4
|
||||
// semmle-extractor-options: --clang -emit-pch -o ${testdir}/clang-pch.testproj/a.pch
|
||||
@@ -1,4 +0,0 @@
|
||||
int main() {
|
||||
return ONE + FOUR;
|
||||
}
|
||||
// semmle-extractor-options: --clang -include ${testdir}/clang-pch.testproj/a -Iextra_dummy_path
|
||||
@@ -1,2 +0,0 @@
|
||||
#import "d.h"
|
||||
// semmle-extractor-options: --clang -emit-pch -o ${testdir}/clang-pch.testproj/d.pch
|
||||
@@ -1,4 +0,0 @@
|
||||
int main() {
|
||||
return SEVENTEEN;
|
||||
}
|
||||
// semmle-extractor-options: --clang -include-pch ${testdir}/clang-pch.testproj/d.pch
|
||||
@@ -1,6 +0,0 @@
|
||||
#if 1
|
||||
#pragma hdrstop
|
||||
extern int x;
|
||||
#define SEEN_F
|
||||
#endif
|
||||
// semmle-extractor-options: --clang -emit-pch -o ${testdir}/clang-pch.testproj/f.pch
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifdef SEEN_F
|
||||
static int g() {
|
||||
return 20;
|
||||
}
|
||||
#endif
|
||||
// semmle-extractor-options: --clang -include-pch ${testdir}/clang-pch.testproj/f.pch
|
||||
@@ -1,5 +0,0 @@
|
||||
#include "h1.h"
|
||||
#pragma hdrstop
|
||||
#include "h2.h"
|
||||
#define SEEN_H
|
||||
// semmle-extractor-options: --clang -emit-pch -o ${testdir}/clang-pch.testproj/h.pch
|
||||
@@ -1,3 +0,0 @@
|
||||
// This file exists to ensure that the output subdirectory exists prior to
|
||||
// a.c being indexed, as said directory needs to exist for the PCH file to
|
||||
// be created, and will be created by running the extractor.
|
||||
@@ -1,2 +0,0 @@
|
||||
#include "a.h"
|
||||
// semmle-extractor-options: --microsoft /Yca.h /Fp${testdir}/microsoft-pch.testproj/a.pch
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma hdrstop
|
||||
#include "b.h"
|
||||
|
||||
int b() {
|
||||
return A;
|
||||
}
|
||||
// semmle-extractor-options: --microsoft /Yub.h /Fp${testdir}/microsoft-pch.testproj/a.pch
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "d.h"
|
||||
#include "c.h"
|
||||
|
||||
int c() {
|
||||
return A;
|
||||
}
|
||||
// semmle-extractor-options: --microsoft /Yuc.h /Fp${testdir}/microsoft-pch.testproj/a.pch
|
||||
@@ -1,5 +1,6 @@
|
||||
import cpp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import InlineModelsAsDataTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import cpp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import InlineModelsAsDataTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
|
||||
@@ -3,22 +3,13 @@ edges
|
||||
| test.cpp:30:34:30:34 | b | test.cpp:31:2:31:2 | b | provenance | |
|
||||
| test.cpp:34:31:34:31 | b | test.cpp:35:2:35:2 | b | provenance | |
|
||||
| test.cpp:57:19:57:19 | d | test.cpp:26:29:26:29 | b | provenance | |
|
||||
| test.cpp:57:19:57:19 | d | test.cpp:58:25:58:25 | d | provenance | |
|
||||
| test.cpp:57:19:57:19 | d | test.cpp:59:21:59:21 | d | provenance | |
|
||||
| test.cpp:58:25:58:25 | d | test.cpp:30:34:30:34 | b | provenance | |
|
||||
| test.cpp:58:25:58:25 | d | test.cpp:59:21:59:21 | d | provenance | |
|
||||
| test.cpp:59:21:59:21 | d | test.cpp:34:31:34:31 | b | provenance | |
|
||||
| test.cpp:74:19:74:21 | dss | test.cpp:26:29:26:29 | b | provenance | |
|
||||
| test.cpp:74:19:74:21 | dss | test.cpp:75:25:75:27 | dss | provenance | |
|
||||
| test.cpp:74:19:74:21 | dss | test.cpp:76:21:76:23 | dss | provenance | |
|
||||
| test.cpp:75:25:75:27 | dss | test.cpp:30:34:30:34 | b | provenance | |
|
||||
| test.cpp:75:25:75:27 | dss | test.cpp:76:21:76:23 | dss | provenance | |
|
||||
| test.cpp:76:21:76:23 | dss | test.cpp:34:31:34:31 | b | provenance | |
|
||||
| test.cpp:86:19:86:20 | d2 | test.cpp:26:29:26:29 | b | provenance | |
|
||||
| test.cpp:86:19:86:20 | d2 | test.cpp:87:25:87:26 | d2 | provenance | |
|
||||
| test.cpp:86:19:86:20 | d2 | test.cpp:88:21:88:22 | d2 | provenance | |
|
||||
| test.cpp:87:25:87:26 | d2 | test.cpp:30:34:30:34 | b | provenance | |
|
||||
| test.cpp:87:25:87:26 | d2 | test.cpp:88:21:88:22 | d2 | provenance | |
|
||||
| test.cpp:88:21:88:22 | d2 | test.cpp:34:31:34:31 | b | provenance | |
|
||||
nodes
|
||||
| test.cpp:26:29:26:29 | b | semmle.label | b |
|
||||
@@ -41,18 +32,9 @@ subpaths
|
||||
| test.cpp:27:2:27:2 | b | test.cpp:57:19:57:19 | d | test.cpp:27:2:27:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:57:19:57:19 | d | this cast |
|
||||
| test.cpp:27:2:27:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:27:2:27:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:74:19:74:21 | dss | this cast |
|
||||
| test.cpp:27:2:27:2 | b | test.cpp:86:19:86:20 | d2 | test.cpp:27:2:27:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:86:19:86:20 | d2 | this cast |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:57:19:57:19 | d | test.cpp:31:2:31:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:57:19:57:19 | d | this cast |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:58:25:58:25 | d | test.cpp:31:2:31:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:58:25:58:25 | d | this cast |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:31:2:31:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:74:19:74:21 | dss | this cast |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:75:25:75:27 | dss | test.cpp:31:2:31:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:75:25:75:27 | dss | this cast |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:86:19:86:20 | d2 | test.cpp:31:2:31:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:86:19:86:20 | d2 | this cast |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:87:25:87:26 | d2 | test.cpp:31:2:31:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:87:25:87:26 | d2 | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:57:19:57:19 | d | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:57:19:57:19 | d | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:58:25:58:25 | d | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:58:25:58:25 | d | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:59:21:59:21 | d | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:59:21:59:21 | d | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:74:19:74:21 | dss | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:75:25:75:27 | dss | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:75:25:75:27 | dss | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:76:21:76:23 | dss | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:76:21:76:23 | dss | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:86:19:86:20 | d2 | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:86:19:86:20 | d2 | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:87:25:87:26 | d2 | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:87:25:87:26 | d2 | this cast |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:88:21:88:22 | d2 | test.cpp:35:2:35:2 | b | This pointer arithmetic may be done with the wrong type because of $@. | test.cpp:88:21:88:22 | d2 | this cast |
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @id cs/invalid-string-formatting
|
||||
* @tags reliability
|
||||
* maintainability
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @id cs/local-not-disposed
|
||||
* @tags efficiency
|
||||
* maintainability
|
||||
* quality
|
||||
* external/cwe/cwe-404
|
||||
* external/cwe/cwe-459
|
||||
* external/cwe/cwe-460
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @id cs/constant-condition
|
||||
* @tags maintainability
|
||||
* readability
|
||||
* quality
|
||||
* external/cwe/cwe-835
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @precision medium
|
||||
* @id cs/password-in-configuration
|
||||
* @tags security
|
||||
* external/cwe/cwe-13
|
||||
* external/cwe/cwe-013
|
||||
* external/cwe/cwe-256
|
||||
* external/cwe/cwe-313
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* @problem.severity warning
|
||||
* @id cs/useless-assignment-to-local
|
||||
* @tags maintainability
|
||||
* quality
|
||||
* external/cwe/cwe-563
|
||||
* @precision very-high
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* logic
|
||||
* quality
|
||||
* external/cwe/cwe-193
|
||||
*/
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* logic
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* logic
|
||||
* quality
|
||||
* external/cwe/cwe-480
|
||||
* external/cwe/cwe-691
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @id cs/equality-on-floats
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @id cs/reference-equality-on-valuetypes
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* quality
|
||||
* external/cwe/cwe-595
|
||||
*/
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* logic
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @id cs/unchecked-cast-in-equals
|
||||
* @tags reliability
|
||||
* maintainability
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
* @problem.severity recommendation
|
||||
* @precision high
|
||||
* @id cs/inefficient-containskey
|
||||
* @tags maintainability efficiency
|
||||
* @tags maintainability
|
||||
* efficiency
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @tags security
|
||||
* maintainability
|
||||
* frameworks/asp.net
|
||||
* external/cwe/cwe-11
|
||||
* external/cwe/cwe-011
|
||||
* external/cwe/cwe-532
|
||||
*/
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @id cs/web/large-max-request-length
|
||||
* @tags security
|
||||
* frameworks/asp.net
|
||||
* external/cwe/cwe-16
|
||||
* external/cwe/cwe-016
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @id cs/web/request-validation-disabled
|
||||
* @tags security
|
||||
* frameworks/asp.net
|
||||
* external/cwe/cwe-16
|
||||
* external/cwe/cwe-016
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* to it.
|
||||
* @id cs/count-untrusted-data-external-api
|
||||
* @kind table
|
||||
* @tags security external/cwe/cwe-20
|
||||
* @tags security external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @security-severity 7.8
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import semmle.code.csharp.serialization.Serialization
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @precision low
|
||||
* @problem.severity error
|
||||
* @security-severity 7.8
|
||||
* @tags security external/cwe/cwe-20
|
||||
* @tags security external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @precision high
|
||||
* @id cs/web/missing-global-error-handler
|
||||
* @tags security
|
||||
* external/cwe/cwe-12
|
||||
* external/cwe/cwe-012
|
||||
* external/cwe/cwe-248
|
||||
*/
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @id cs/call-to-object-tostring
|
||||
* @tags reliability
|
||||
* maintainability
|
||||
* quality
|
||||
*/
|
||||
|
||||
import DefaultToStringQuery
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @id cs/useless-gethashcode-call
|
||||
* @tags readability
|
||||
* useless-code
|
||||
* quality
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
12
csharp/ql/src/change-notes/2025-05-01-cwe-tag-changed.md
Normal file
12
csharp/ql/src/change-notes/2025-05-01-cwe-tag-changed.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
|
||||
* The tag `external/cwe/cwe-13` has been removed from `cs/password-in-configuration` and the tag `external/cwe/cwe-013` has been added.
|
||||
* The tag `external/cwe/cwe-11` has been removed from `cs/web/debug-binary` and the tag `external/cwe/cwe-011` has been added.
|
||||
* The tag `external/cwe/cwe-16` has been removed from `cs/web/large-max-request-length` and the tag `external/cwe/cwe-016` has been added.
|
||||
* The tag `external/cwe/cwe-16` has been removed from `cs/web/request-validation-disabled` and the tag `external/cwe/cwe-016` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cs/count-untrusted-data-external-api` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cs/serialization-check-bypass` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-20` has been removed from `cs/untrusted-data-to-external-api` and the tag `external/cwe/cwe-020` has been added.
|
||||
* The tag `external/cwe/cwe-12` has been removed from `cs/web/missing-global-error-handler` and the tag `external/cwe/cwe-012` has been added.
|
||||
@@ -1,17 +1,3 @@
|
||||
- queries: .
|
||||
- include:
|
||||
id:
|
||||
- cs/index-out-of-bounds
|
||||
- cs/test-for-negative-container-size
|
||||
- cs/unchecked-cast-in-equals
|
||||
- cs/reference-equality-on-valuetypes
|
||||
- cs/self-assignment
|
||||
- cs/inefficient-containskey
|
||||
- cs/call-to-object-tostring
|
||||
- cs/local-not-disposed
|
||||
- cs/constant-condition
|
||||
- cs/useless-gethashcode-call
|
||||
- cs/non-short-circuit
|
||||
- cs/useless-assignment-to-local
|
||||
- cs/invalid-string-formatting
|
||||
- cs/equality-on-floats
|
||||
- apply: code-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SummaryModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string flow
|
||||
where flow = ContentSensitive::captureFlow(api, _)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SummaryModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string noflow
|
||||
where noflow = captureNeutral(api)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SinkModels
|
||||
|
||||
from DataFlowSinkTargetApi api, string sink
|
||||
where sink = Heuristic::captureSink(api)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SourceModels
|
||||
|
||||
from DataFlowSourceTargetApi api, string source
|
||||
where source = Heuristic::captureSource(api)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import SummaryModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string flow
|
||||
where flow = captureFlow(api, _)
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
* @precision low
|
||||
* @id csharp/utils/modelgenerator/summary-models-partial-path
|
||||
* @severity info
|
||||
* @tags modelgenerator
|
||||
* @tags debugmodelgenerator
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import PartialFlow::PartialPathGraph
|
||||
|
||||
int explorationLimit() { result = 3 }
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
* @precision low
|
||||
* @id csharp/utils/modelgenerator/summary-models-path
|
||||
* @severity warning
|
||||
* @tags modelgenerator
|
||||
* @tags debugmodelgenerator
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import Heuristic
|
||||
import PropagateFlow::PathGraph
|
||||
|
||||
|
||||
@@ -15,7 +15,41 @@ private import semmle.code.csharp.frameworks.System
|
||||
private import semmle.code.csharp.Location
|
||||
private import codeql.mad.modelgenerator.internal.ModelGeneratorImpl
|
||||
|
||||
module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDataFlow> {
|
||||
private predicate irrelevantAccessor(CS::Accessor a) {
|
||||
a.getDeclaration().(CS::Property).isReadWrite()
|
||||
}
|
||||
|
||||
private predicate isUninterestingForModels(Callable api) {
|
||||
api.getDeclaringType().getNamespace().getFullName() = ""
|
||||
or
|
||||
api instanceof CS::ConversionOperator
|
||||
or
|
||||
api instanceof Util::MainMethod
|
||||
or
|
||||
api instanceof CS::Destructor
|
||||
or
|
||||
api instanceof CS::AnonymousFunctionExpr
|
||||
or
|
||||
api.(CS::Constructor).isParameterless()
|
||||
or
|
||||
exists(Type decl | decl = api.getDeclaringType() |
|
||||
decl instanceof SystemObjectClass or
|
||||
decl instanceof SystemValueTypeClass
|
||||
)
|
||||
or
|
||||
// Disregard properties that have both a get and a set accessor,
|
||||
// which implicitly means auto implemented properties.
|
||||
irrelevantAccessor(api)
|
||||
}
|
||||
|
||||
private predicate relevant(Callable api) {
|
||||
[api.(CS::Modifiable), api.(CS::Accessor).getDeclaration()].isEffectivelyPublic() and
|
||||
api.fromSource() and
|
||||
api.isUnboundDeclaration() and
|
||||
not isUninterestingForModels(api)
|
||||
}
|
||||
|
||||
module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Location, CsharpDataFlow> {
|
||||
class Type = CS::Type;
|
||||
|
||||
class Parameter = CS::Parameter;
|
||||
@@ -24,127 +58,8 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
|
||||
|
||||
class NodeExtended = CS::DataFlow::Node;
|
||||
|
||||
Callable getAsExprEnclosingCallable(NodeExtended node) {
|
||||
result = node.asExpr().getEnclosingCallable()
|
||||
}
|
||||
|
||||
Callable getEnclosingCallable(NodeExtended node) { result = node.getEnclosingCallable() }
|
||||
|
||||
Parameter asParameter(NodeExtended node) { result = node.asParameter() }
|
||||
|
||||
/**
|
||||
* Holds if any of the parameters of `api` are `System.Func<>`.
|
||||
*/
|
||||
private predicate isHigherOrder(Callable api) {
|
||||
exists(Type t | t = api.getAParameter().getType().getUnboundDeclaration() |
|
||||
t instanceof SystemLinqExpressions::DelegateExtType
|
||||
)
|
||||
}
|
||||
|
||||
private predicate irrelevantAccessor(CS::Accessor a) {
|
||||
a.getDeclaration().(CS::Property).isReadWrite()
|
||||
}
|
||||
|
||||
private predicate isUninterestingForModels(Callable api) {
|
||||
api.getDeclaringType().getNamespace().getFullName() = ""
|
||||
or
|
||||
api instanceof CS::ConversionOperator
|
||||
or
|
||||
api instanceof Util::MainMethod
|
||||
or
|
||||
api instanceof CS::Destructor
|
||||
or
|
||||
api instanceof CS::AnonymousFunctionExpr
|
||||
or
|
||||
api.(CS::Constructor).isParameterless()
|
||||
or
|
||||
exists(Type decl | decl = api.getDeclaringType() |
|
||||
decl instanceof SystemObjectClass or
|
||||
decl instanceof SystemValueTypeClass
|
||||
)
|
||||
or
|
||||
// Disregard properties that have both a get and a set accessor,
|
||||
// which implicitly means auto implemented properties.
|
||||
irrelevantAccessor(api)
|
||||
}
|
||||
|
||||
private predicate relevant(Callable api) {
|
||||
[api.(CS::Modifiable), api.(CS::Accessor).getDeclaration()].isEffectivelyPublic() and
|
||||
api.fromSource() and
|
||||
api.isUnboundDeclaration() and
|
||||
not isUninterestingForModels(api)
|
||||
}
|
||||
|
||||
private Callable getARelevantOverrideeOrImplementee(Overridable m) {
|
||||
m.overridesOrImplements(result) and relevant(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the super implementation of `api` if it is relevant.
|
||||
* If such a super implementation does not exist, returns `api` if it is relevant.
|
||||
*/
|
||||
private Callable liftedImpl(Callable api) {
|
||||
(
|
||||
result = getARelevantOverrideeOrImplementee(api)
|
||||
or
|
||||
result = api and relevant(api)
|
||||
) and
|
||||
not exists(getARelevantOverrideeOrImplementee(result))
|
||||
}
|
||||
|
||||
private predicate hasManualSummaryModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
private predicate hasManualSourceModel(Callable api) {
|
||||
api = any(ExternalFlow::SourceCallable sc | sc.hasManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSourceCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
private predicate hasManualSinkModel(Callable api) {
|
||||
api = any(ExternalFlow::SinkCallable sc | sc.hasManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
predicate isUninterestingForDataFlowModels(Callable api) { none() }
|
||||
|
||||
predicate isUninterestingForHeuristicDataFlowModels(Callable api) { isHigherOrder(api) }
|
||||
|
||||
class SourceOrSinkTargetApi extends Callable {
|
||||
SourceOrSinkTargetApi() { relevant(this) }
|
||||
}
|
||||
|
||||
class SinkTargetApi extends SourceOrSinkTargetApi {
|
||||
SinkTargetApi() { not hasManualSinkModel(this) }
|
||||
}
|
||||
|
||||
class SourceTargetApi extends SourceOrSinkTargetApi {
|
||||
SourceTargetApi() {
|
||||
not hasManualSourceModel(this) and
|
||||
// Do not generate source models for overridable callables
|
||||
// as virtual dispatch implies that too many methods
|
||||
// will be considered sources.
|
||||
not this.(Overridable).overridesOrImplements(_)
|
||||
}
|
||||
}
|
||||
|
||||
class SummaryTargetApi extends Callable {
|
||||
private Callable lift;
|
||||
|
||||
SummaryTargetApi() {
|
||||
lift = liftedImpl(this) and
|
||||
not hasManualSummaryModel(lift)
|
||||
}
|
||||
|
||||
Callable lift() { result = lift }
|
||||
|
||||
predicate isRelevant() {
|
||||
relevant(this) and
|
||||
not hasManualSummaryModel(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `t` is a type that is generally used for bulk data in collection types.
|
||||
* Eg. char[] is roughly equivalent to string and thus a highly
|
||||
@@ -205,6 +120,8 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
|
||||
)
|
||||
}
|
||||
|
||||
class InstanceParameterNode = DataFlowPrivate::InstanceParameterNode;
|
||||
|
||||
string qualifierString() { result = "Argument[this]" }
|
||||
|
||||
string parameterAccess(CS::Parameter p) {
|
||||
@@ -215,8 +132,6 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
|
||||
|
||||
string parameterContentAccess(CS::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
|
||||
|
||||
class InstanceParameterNode = DataFlowPrivate::InstanceParameterNode;
|
||||
|
||||
private signature string parameterAccessSig(Parameter p);
|
||||
|
||||
private module ParamReturnNodeAsOutput<parameterAccessSig/1 getParamAccess> {
|
||||
@@ -251,63 +166,92 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
|
||||
node.asExpr() instanceof CS::ThisAccess
|
||||
}
|
||||
|
||||
private predicate isRelevantMemberAccess(DataFlow::Node node) {
|
||||
exists(CS::MemberAccess access | access = node.asExpr() |
|
||||
access.hasThisQualifier() and
|
||||
access.getTarget().isEffectivelyPublic() and
|
||||
(
|
||||
access instanceof CS::FieldAccess
|
||||
or
|
||||
access.getTarget().(CS::Property).getSetter().isPublic()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate sinkModelSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
predicate apiSource(DataFlow::Node source) {
|
||||
isRelevantMemberAccess(source) or source instanceof DataFlow::ParameterNode
|
||||
}
|
||||
|
||||
private predicate uniquelyCalls(DataFlowCallable dc1, DataFlowCallable dc2) {
|
||||
exists(DataFlowCall call |
|
||||
dc1 = call.getEnclosingCallable() and
|
||||
dc2 = unique(DataFlowCallable dc0 | dc0 = viableCallable(call) | dc0)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[dc1, dc2]
|
||||
private predicate uniquelyCallsPlus(DataFlowCallable dc1, DataFlowCallable dc2) =
|
||||
fastTC(uniquelyCalls/2)(dc1, dc2)
|
||||
|
||||
bindingset[sourceEnclosing, api]
|
||||
predicate irrelevantSourceSinkApi(Callable sourceEnclosing, SourceTargetApi api) {
|
||||
not exists(DataFlowCallable dc1, DataFlowCallable dc2 |
|
||||
uniquelyCallsPlus(dc1, dc2) or dc1 = dc2
|
||||
|
|
||||
dc1.getUnderlyingCallable() = api and
|
||||
dc2.getUnderlyingCallable() = sourceEnclosing
|
||||
)
|
||||
}
|
||||
|
||||
string getInputArgument(DataFlow::Node source) {
|
||||
exists(int pos |
|
||||
pos = source.(DataFlow::ParameterNode).getParameter().getPosition() and
|
||||
result = "Argument[" + pos + "]"
|
||||
)
|
||||
or
|
||||
source.asExpr() instanceof DataFlowPrivate::FieldOrPropertyAccess and
|
||||
result = qualifierString()
|
||||
}
|
||||
|
||||
bindingset[kind]
|
||||
predicate isRelevantSinkKind(string kind) { any() }
|
||||
|
||||
bindingset[kind]
|
||||
predicate isRelevantSourceKind(string kind) { any() }
|
||||
|
||||
predicate containerContent(DataFlow::ContentSet c) { c.isElement() }
|
||||
|
||||
string partialModelRow(Callable api, int i) {
|
||||
i = 0 and ExternalFlow::partialModel(api, result, _, _, _, _) // package
|
||||
or
|
||||
i = 1 and ExternalFlow::partialModel(api, _, result, _, _, _) // type
|
||||
or
|
||||
i = 2 and ExternalFlow::partialModel(api, _, _, result, _, _) // extensible
|
||||
or
|
||||
i = 3 and ExternalFlow::partialModel(api, _, _, _, result, _) // name
|
||||
or
|
||||
i = 4 and ExternalFlow::partialModel(api, _, _, _, _, result) // parameters
|
||||
or
|
||||
i = 5 and result = "" and exists(api) // ext
|
||||
}
|
||||
|
||||
string partialNeutralModelRow(Callable api, int i) {
|
||||
i = 0 and result = partialModelRow(api, 0) // package
|
||||
or
|
||||
i = 1 and result = partialModelRow(api, 1) // type
|
||||
or
|
||||
i = 2 and result = partialModelRow(api, 3) // name
|
||||
or
|
||||
i = 3 and result = partialModelRow(api, 4) // parameters
|
||||
}
|
||||
}
|
||||
|
||||
private import ModelGeneratorCommonInput
|
||||
private import MakeModelGeneratorFactory<Location, CsharpDataFlow, CsharpTaintTracking, ModelGeneratorCommonInput>
|
||||
|
||||
module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
|
||||
Callable getAsExprEnclosingCallable(NodeExtended node) {
|
||||
result = node.asExpr().getEnclosingCallable()
|
||||
}
|
||||
|
||||
Parameter asParameter(NodeExtended node) { result = node.asParameter() }
|
||||
|
||||
/**
|
||||
* Holds if any of the parameters of `api` are `System.Func<>`.
|
||||
*/
|
||||
private predicate isHigherOrder(Callable api) {
|
||||
exists(Type t | t = api.getAParameter().getType().getUnboundDeclaration() |
|
||||
t instanceof SystemLinqExpressions::DelegateExtType
|
||||
)
|
||||
}
|
||||
|
||||
private Callable getARelevantOverrideeOrImplementee(Overridable m) {
|
||||
m.overridesOrImplements(result) and relevant(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the super implementation of `api` if it is relevant.
|
||||
* If such a super implementation does not exist, returns `api` if it is relevant.
|
||||
*/
|
||||
private Callable liftedImpl(Callable api) {
|
||||
(
|
||||
result = getARelevantOverrideeOrImplementee(api)
|
||||
or
|
||||
result = api and relevant(api)
|
||||
) and
|
||||
not exists(getARelevantOverrideeOrImplementee(result))
|
||||
}
|
||||
|
||||
private predicate hasManualSummaryModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
predicate isUninterestingForHeuristicDataFlowModels(Callable api) { isHigherOrder(api) }
|
||||
|
||||
class SummaryTargetApi extends Callable {
|
||||
private Callable lift;
|
||||
|
||||
SummaryTargetApi() {
|
||||
lift = liftedImpl(this) and
|
||||
not hasManualSummaryModel(lift)
|
||||
}
|
||||
|
||||
Callable lift() { result = lift }
|
||||
|
||||
predicate isRelevant() {
|
||||
relevant(this) and
|
||||
not hasManualSummaryModel(this)
|
||||
}
|
||||
}
|
||||
|
||||
predicate isAdditionalContentFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
TaintTrackingPrivate::defaultAdditionalTaintStep(nodeFrom, nodeTo, _) and
|
||||
not nodeTo.asExpr() instanceof CS::ElementAccess and
|
||||
@@ -370,34 +314,88 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
|
||||
or
|
||||
c.isDelegateCallReturn() and result = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
string partialModelRow(Callable api, int i) {
|
||||
i = 0 and ExternalFlow::partialModel(api, result, _, _, _, _) // package
|
||||
or
|
||||
i = 1 and ExternalFlow::partialModel(api, _, result, _, _, _) // type
|
||||
or
|
||||
i = 2 and ExternalFlow::partialModel(api, _, _, result, _, _) // extensible
|
||||
or
|
||||
i = 3 and ExternalFlow::partialModel(api, _, _, _, result, _) // name
|
||||
or
|
||||
i = 4 and ExternalFlow::partialModel(api, _, _, _, _, result) // parameters
|
||||
or
|
||||
i = 5 and result = "" and exists(api) // ext
|
||||
private module SourceModelGeneratorInput implements SourceModelGeneratorInputSig {
|
||||
private predicate hasManualSourceModel(Callable api) {
|
||||
api = any(ExternalFlow::SourceCallable sc | sc.hasManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSourceCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
string partialNeutralModelRow(Callable api, int i) {
|
||||
i = 0 and result = partialModelRow(api, 0) // package
|
||||
or
|
||||
i = 1 and result = partialModelRow(api, 1) // type
|
||||
or
|
||||
i = 2 and result = partialModelRow(api, 3) // name
|
||||
or
|
||||
i = 3 and result = partialModelRow(api, 4) // parameters
|
||||
class SourceTargetApi extends Callable {
|
||||
SourceTargetApi() {
|
||||
relevant(this) and
|
||||
not hasManualSourceModel(this) and
|
||||
// Do not generate source models for overridable callables
|
||||
// as virtual dispatch implies that too many methods
|
||||
// will be considered sources.
|
||||
not this.(Overridable).overridesOrImplements(_)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate uniquelyCalls(DataFlowCallable dc1, DataFlowCallable dc2) {
|
||||
exists(DataFlowCall call |
|
||||
dc1 = call.getEnclosingCallable() and
|
||||
dc2 = unique(DataFlowCallable dc0 | dc0 = viableCallable(call) | dc0)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[dc1, dc2]
|
||||
private predicate uniquelyCallsPlus(DataFlowCallable dc1, DataFlowCallable dc2) =
|
||||
fastTC(uniquelyCalls/2)(dc1, dc2)
|
||||
|
||||
bindingset[sourceEnclosing, api]
|
||||
predicate irrelevantSourceSinkApi(Callable sourceEnclosing, SourceTargetApi api) {
|
||||
not exists(DataFlowCallable dc1, DataFlowCallable dc2 |
|
||||
uniquelyCallsPlus(dc1, dc2) or dc1 = dc2
|
||||
|
|
||||
dc1.getUnderlyingCallable() = api and
|
||||
dc2.getUnderlyingCallable() = sourceEnclosing
|
||||
)
|
||||
}
|
||||
|
||||
predicate sourceNode = ExternalFlow::sourceNode/2;
|
||||
}
|
||||
|
||||
private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
|
||||
private predicate hasManualSinkModel(Callable api) {
|
||||
api = any(ExternalFlow::SinkCallable sc | sc.hasManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
class SinkTargetApi extends Callable {
|
||||
SinkTargetApi() { relevant(this) and not hasManualSinkModel(this) }
|
||||
}
|
||||
|
||||
private predicate isRelevantMemberAccess(DataFlow::Node node) {
|
||||
exists(CS::MemberAccess access | access = node.asExpr() |
|
||||
access.hasThisQualifier() and
|
||||
access.getTarget().isEffectivelyPublic() and
|
||||
(
|
||||
access instanceof CS::FieldAccess
|
||||
or
|
||||
access.getTarget().(CS::Property).getSetter().isPublic()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate apiSource(DataFlow::Node source) {
|
||||
isRelevantMemberAccess(source) or source instanceof DataFlow::ParameterNode
|
||||
}
|
||||
|
||||
string getInputArgument(DataFlow::Node source) {
|
||||
exists(int pos |
|
||||
pos = source.(DataFlow::ParameterNode).getParameter().getPosition() and
|
||||
result = "Argument[" + pos + "]"
|
||||
)
|
||||
or
|
||||
source.asExpr() instanceof DataFlowPrivate::FieldOrPropertyAccess and
|
||||
result = qualifierString()
|
||||
}
|
||||
|
||||
predicate sinkNode = ExternalFlow::sinkNode/2;
|
||||
}
|
||||
|
||||
import MakeModelGenerator<Location, CsharpDataFlow, CsharpTaintTracking, ModelGeneratorInput>
|
||||
import MakeSummaryModelGenerator<SummaryModelGeneratorInput> as SummaryModels
|
||||
import MakeSourceModelGenerator<SourceModelGeneratorInput> as SourceModels
|
||||
import MakeSinkModelGenerator<SinkModelGeneratorInput> as SinkModels
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import csharp as CS
|
||||
private import codeql.mad.modelgenerator.internal.ModelPrinting
|
||||
private import CaptureModels::ModelGeneratorInput as ModelGeneratorInput
|
||||
private import CaptureModels::ModelGeneratorCommonInput as ModelGeneratorInput
|
||||
|
||||
private module ModelPrintingLang implements ModelPrintingLangSig {
|
||||
class Callable = CS::Callable;
|
||||
|
||||
@@ -2,7 +2,8 @@ private import csharp
|
||||
private import semmle.code.csharp.frameworks.system.collections.Generic as GenericCollections
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.csharp.frameworks.system.linq.Expressions
|
||||
private import CaptureModels::ModelGeneratorInput as ModelGeneratorInput
|
||||
private import CaptureModels::ModelGeneratorCommonInput as ModelGeneratorInput
|
||||
private import CaptureModels::SummaryModelGeneratorInput as SummaryModelGeneratorInput
|
||||
private import CaptureModelsPrinting
|
||||
|
||||
/**
|
||||
@@ -177,21 +178,19 @@ private predicate output(Callable callable, TypeParameter tp, string output) {
|
||||
delegateSink(callable, tp, output)
|
||||
}
|
||||
|
||||
private module ModelPrintingInput implements ModelPrintingSig {
|
||||
private module ModelPrintingInput implements ModelPrintingSummarySig {
|
||||
class SummaryApi = TypeBasedFlowTargetApi;
|
||||
|
||||
class SourceOrSinkApi = TypeBasedFlowTargetApi;
|
||||
|
||||
string getProvenance() { result = "tb-generated" }
|
||||
}
|
||||
|
||||
private module Printing = ModelPrinting<ModelPrintingInput>;
|
||||
private module Printing = ModelPrintingSummary<ModelPrintingInput>;
|
||||
|
||||
/**
|
||||
* A class of callables that are relevant generating summaries for based
|
||||
* on the Theorems for Free approach.
|
||||
*/
|
||||
class TypeBasedFlowTargetApi extends ModelGeneratorInput::SummaryTargetApi {
|
||||
class TypeBasedFlowTargetApi extends SummaryModelGeneratorInput::SummaryTargetApi {
|
||||
/**
|
||||
* Gets the string representation of all type based summaries for `this`
|
||||
* inspired by the Theorems for Free approach.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import csharp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import utils.test.InlineMadTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import csharp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import utils.test.InlineMadTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import csharp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SummaryModels
|
||||
import utils.test.InlineMadTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import csharp
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import SinkModels
|
||||
import utils.test.InlineMadTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user