Compare commits

..

4 Commits

Author SHA1 Message Date
Napalys Klicius
84ffbbec33 Added missing doc strings 2025-07-30 10:51:38 +00:00
Napalys Klicius
95743d7109 Added inline test expectations for cors permissive config 2025-07-30 10:42:55 +00:00
Napalys Klicius
92daa7d42c Updated suite expectations 2025-07-30 10:32:11 +00:00
Napalys Klicius
358617f533 Move CORS misconfiguration query from experimental to Security 2025-07-30 10:22:59 +00:00
229 changed files with 362 additions and 1379 deletions

View File

@@ -230,7 +230,7 @@ use_repo(
"kotlin-compiler-2.1.0-Beta1", "kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-2.1.20-Beta1", "kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-2.2.0-Beta1", "kotlin-compiler-2.2.0-Beta1",
"kotlin-compiler-2.2.20-Beta2", "kotlin-compiler-2.2.20-Beta1",
"kotlin-compiler-embeddable-1.6.0", "kotlin-compiler-embeddable-1.6.0",
"kotlin-compiler-embeddable-1.6.20", "kotlin-compiler-embeddable-1.6.20",
"kotlin-compiler-embeddable-1.7.0", "kotlin-compiler-embeddable-1.7.0",
@@ -243,7 +243,7 @@ use_repo(
"kotlin-compiler-embeddable-2.1.0-Beta1", "kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-compiler-embeddable-2.1.20-Beta1", "kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-compiler-embeddable-2.2.0-Beta1", "kotlin-compiler-embeddable-2.2.0-Beta1",
"kotlin-compiler-embeddable-2.2.20-Beta2", "kotlin-compiler-embeddable-2.2.20-Beta1",
"kotlin-stdlib-1.6.0", "kotlin-stdlib-1.6.0",
"kotlin-stdlib-1.6.20", "kotlin-stdlib-1.6.20",
"kotlin-stdlib-1.7.0", "kotlin-stdlib-1.7.0",
@@ -256,7 +256,7 @@ use_repo(
"kotlin-stdlib-2.1.0-Beta1", "kotlin-stdlib-2.1.0-Beta1",
"kotlin-stdlib-2.1.20-Beta1", "kotlin-stdlib-2.1.20-Beta1",
"kotlin-stdlib-2.2.0-Beta1", "kotlin-stdlib-2.2.0-Beta1",
"kotlin-stdlib-2.2.20-Beta2", "kotlin-stdlib-2.2.20-Beta1",
) )
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -1,7 +1,3 @@
## 0.4.14
No user-facing changes.
## 0.4.13 ## 0.4.13
### Bug Fixes ### Bug Fixes

View File

@@ -1,3 +0,0 @@
## 0.4.14
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.14 lastReleaseVersion: 0.4.13

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all name: codeql/actions-all
version: 0.4.14 version: 0.4.14-dev
library: true library: true
warnOnImplicitThis: true warnOnImplicitThis: true
dependencies: dependencies:

View File

@@ -1,7 +1,3 @@
## 0.6.6
No user-facing changes.
## 0.6.5 ## 0.6.5
No user-facing changes. No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.6.6
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.6.6 lastReleaseVersion: 0.6.5

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries name: codeql/actions-queries
version: 0.6.6 version: 0.6.6-dev
library: false library: false
warnOnImplicitThis: true warnOnImplicitThis: true
groups: [actions, queries] groups: [actions, queries]

View File

@@ -1,13 +1,3 @@
## 5.4.0
### New Features
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
### Minor Analysis Improvements
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
## 5.3.0 ## 5.3.0
### Deprecated APIs ### Deprecated APIs

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.

View File

@@ -1,9 +0,0 @@
## 5.4.0
### New Features
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
### Minor Analysis Improvements
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 5.4.0 lastReleaseVersion: 5.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all name: codeql/cpp-all
version: 5.4.0 version: 5.3.1-dev
groups: cpp groups: cpp
dbscheme: semmlecode.cpp.dbscheme dbscheme: semmlecode.cpp.dbscheme
extractor: cpp extractor: cpp

View File

@@ -15,13 +15,6 @@ class StandardSsa extends SsaHelper {
} }
/** /**
* NOTE: If possible, prefer the SSA classes exposed by the new dataflow
* library:
* ```
* import semmle.code.cpp.dataflow.new.DataFlow
* // use `DataFlow::Ssa::Definition`
* ```
*
* A definition of one or more SSA variables, including phi node definitions. * A definition of one or more SSA variables, including phi node definitions.
* An _SSA variable_, as defined in the literature, is effectively the pair of * An _SSA variable_, as defined in the literature, is effectively the pair of
* an `SsaDefinition d` and a `StackVariable v`, written `(d, v)` in this * an `SsaDefinition d` and a `StackVariable v`, written `(d, v)` in this

View File

@@ -1,5 +1,6 @@
private import cpp private import cpp
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import DataFlowPrivate private import DataFlowPrivate
private import DataFlowUtil private import DataFlowUtil
private import DataFlowImplCommon as DataFlowImplCommon private import DataFlowImplCommon as DataFlowImplCommon
@@ -59,7 +60,7 @@ private module VirtualDispatch {
* `resolve` predicate to stitch that information together and resolve the * `resolve` predicate to stitch that information together and resolve the
* call. * call.
*/ */
abstract Node getDispatchValue(); abstract DataFlow::Node getDispatchValue();
/** Gets a candidate target for this call. */ /** Gets a candidate target for this call. */
abstract Function resolve(); abstract Function resolve();
@@ -71,13 +72,17 @@ private module VirtualDispatch {
* parameter is true when the search is allowed to continue backwards into * parameter is true when the search is allowed to continue backwards into
* a parameter; non-recursive callers should pass `_` for `allowFromArg`. * a parameter; non-recursive callers should pass `_` for `allowFromArg`.
*/ */
predicate flowsFrom(Node src, boolean allowFromArg) { predicate flowsFrom(DataFlow::Node src, boolean allowFromArg) {
src = this.getDispatchValue() and allowFromArg = true src = this.getDispatchValue() and allowFromArg = true
or or
exists(Node other, boolean allowOtherFromArg | this.flowsFrom(other, allowOtherFromArg) | exists(DataFlow::Node other, boolean allowOtherFromArg |
this.flowsFrom(other, allowOtherFromArg)
|
// Call argument // Call argument
exists(DataFlowCall call, Position i | exists(DataFlowCall call, Position i |
other.(ParameterNode).isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and other
.(DataFlow::ParameterNode)
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i))) src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i)))
) and ) and
allowOtherFromArg = true and allowOtherFromArg = true and
@@ -91,7 +96,7 @@ private module VirtualDispatch {
allowFromArg = false allowFromArg = false
or or
// Local flow // Local flow
localFlowStep(src, other) and DataFlow::localFlowStep(src, other) and
allowFromArg = allowOtherFromArg allowFromArg = allowOtherFromArg
or or
// Flow from global variable to load. // Flow from global variable to load.
@@ -154,11 +159,11 @@ private module VirtualDispatch {
private class DataSensitiveExprCall extends DataSensitiveCall { private class DataSensitiveExprCall extends DataSensitiveCall {
DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) } DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) }
override Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() } override DataFlow::Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
override Function resolve() { override Function resolve() {
exists(FunctionInstruction fi | exists(FunctionInstruction fi |
this.flowsFrom(instructionNode(fi), _) and this.flowsFrom(DataFlow::instructionNode(fi), _) and
result = fi.getFunctionSymbol() result = fi.getFunctionSymbol()
) and ) and
( (
@@ -181,7 +186,7 @@ private module VirtualDispatch {
) )
} }
override Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) } override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
override MemberFunction resolve() { override MemberFunction resolve() {
exists(Class overridingClass | exists(Class overridingClass |
@@ -208,7 +213,7 @@ private module VirtualDispatch {
pragma[noinline] pragma[noinline]
private predicate hasFlowFromCastFrom(Class derivedClass) { private predicate hasFlowFromCastFrom(Class derivedClass) {
exists(ConvertToBaseInstruction toBase | exists(ConvertToBaseInstruction toBase |
this.flowsFrom(instructionNode(toBase), _) and this.flowsFrom(DataFlow::instructionNode(toBase), _) and
derivedClass = toBase.getDerivedClass() derivedClass = toBase.getDerivedClass()
) )
} }
@@ -265,7 +270,7 @@ private predicate mayBenefitFromCallContext(
exists(InitializeParameterInstruction init | exists(InitializeParameterInstruction init |
not exists(call.getStaticCallTarget()) and not exists(call.getStaticCallTarget()) and
init.getEnclosingFunction() = f.getUnderlyingCallable() and init.getEnclosingFunction() = f.getUnderlyingCallable() and
call.flowsFrom(instructionNode(init), _) and call.flowsFrom(DataFlow::instructionNode(init), _) and
init.getParameter().getIndex() = arg init.getParameter().getIndex() = arg
) )
} }

View File

@@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.IR
private import DataFlowDispatch private import DataFlowDispatch
private import semmle.code.cpp.ir.internal.IRCppLanguage private import semmle.code.cpp.ir.internal.IRCppLanguage
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import SsaImpl as Ssa private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon private import DataFlowImplCommon as DataFlowImplCommon
private import codeql.util.Unit private import codeql.util.Unit
private import Node0ToString private import Node0ToString
@@ -1982,23 +1982,19 @@ module IteratorFlow {
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() } predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
class GuardValue = Void;
class Guard extends Void { class Guard extends Void {
predicate hasValueBranchEdge( predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
) {
none() none()
} }
predicate valueControlsBranchEdge( predicate controlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
) { ) {
none() none()
} }
} }
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) { predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
none() none()
} }

View File

@@ -13,7 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import DataFlowPrivate private import DataFlowPrivate
private import ModelUtil private import ModelUtil
private import SsaImpl as SsaImpl private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon private import DataFlowImplCommon as DataFlowImplCommon
private import codeql.util.Unit private import codeql.util.Unit
private import Node0ToString private import Node0ToString
@@ -39,39 +39,38 @@ private newtype TIRDataFlowNode =
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) { TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) {
indirectionIndex = indirectionIndex =
[getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForType(var.getUnspecifiedType())] [getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
} or } or
TPostUpdateNodeImpl(Operand operand, int indirectionIndex) { TPostUpdateNodeImpl(Operand operand, int indirectionIndex) {
operand = any(FieldAddress fa).getObjectAddressOperand() and operand = any(FieldAddress fa).getObjectAddressOperand() and
indirectionIndex = indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))]
[0 .. SsaImpl::countIndirectionsForCppType(SsaImpl::getLanguageType(operand))]
or or
SsaImpl::isModifiableByCall(operand, indirectionIndex) Ssa::isModifiableByCall(operand, indirectionIndex)
} or } or
TSsaSynthNode(SsaImpl::SynthNode n) or TSsaSynthNode(Ssa::SynthNode n) or
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) { TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
SsaImpl::hasRawIndirectOperand(node.asOperand(), indirectionIndex) Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
} or } or
TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) { TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
not exists(node.asOperand()) and not exists(node.asOperand()) and
SsaImpl::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex) Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
} or } or
TFinalParameterNode(Parameter p, int indirectionIndex) { TFinalParameterNode(Parameter p, int indirectionIndex) {
exists(SsaImpl::FinalParameterUse use | exists(Ssa::FinalParameterUse use |
use.getParameter() = p and use.getParameter() = p and
use.getIndirectionIndex() = indirectionIndex use.getIndirectionIndex() = indirectionIndex
) )
} or } or
TFinalGlobalValue(SsaImpl::GlobalUse globalUse) or TFinalGlobalValue(Ssa::GlobalUse globalUse) or
TInitialGlobalValue(SsaImpl::GlobalDef globalUse) or TInitialGlobalValue(Ssa::GlobalDef globalUse) or
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) { TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
// Rule out parameters of catch blocks. // Rule out parameters of catch blocks.
not exists(p.getCatchBlock()) and not exists(p.getCatchBlock()) and
// We subtract one because `getMaxIndirectionsForType` returns the maximum // We subtract one because `getMaxIndirectionsForType` returns the maximum
// indirection for a glvalue of a given type, and this doesn't apply to // indirection for a glvalue of a given type, and this doesn't apply to
// parameters. // parameters.
indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and indirectionIndex = [0 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
not any(InitializeParameterInstruction init).getParameter() = p not any(InitializeParameterInstruction init).getParameter() = p
} or } or
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
@@ -82,7 +81,7 @@ private newtype TIRDataFlowNode =
class FieldAddress extends Operand { class FieldAddress extends Operand {
FieldAddressInstruction fai; FieldAddressInstruction fai;
FieldAddress() { fai = this.getDef() and not SsaImpl::ignoreOperand(this) } FieldAddress() { fai = this.getDef() and not Ssa::ignoreOperand(this) }
/** Gets the field associated with this instruction. */ /** Gets the field associated with this instruction. */
Field getField() { result = fai.getField() } Field getField() { result = fai.getField() }
@@ -127,7 +126,7 @@ predicate conversionFlow(
) )
or or
additional = true and additional = true and
SsaImpl::isAdditionalConversionFlow(opFrom, instrTo) Ssa::isAdditionalConversionFlow(opFrom, instrTo)
) )
or or
isPointerArith = true and isPointerArith = true and
@@ -184,7 +183,7 @@ class Node extends TIRDataFlowNode {
or or
this.asOperand().getUse() = block.getInstruction(i) this.asOperand().getUse() = block.getInstruction(i)
or or
exists(SsaImpl::SynthNode ssaNode | exists(Ssa::SynthNode ssaNode |
this.(SsaSynthNode).getSynthNode() = ssaNode and this.(SsaSynthNode).getSynthNode() = ssaNode and
ssaNode.getBasicBlock() = block and ssaNode.getBasicBlock() = block and
ssaNode.getIndex() = i ssaNode.getIndex() = i
@@ -365,10 +364,10 @@ class Node extends TIRDataFlowNode {
* pointed to by `p`. * pointed to by `p`.
*/ */
Expr asDefinition(boolean uncertain) { Expr asDefinition(boolean uncertain) {
exists(StoreInstruction store, SsaImpl::Definition def | exists(StoreInstruction store, Ssa::Definition def |
store = this.asInstruction() and store = this.asInstruction() and
result = asDefinitionImpl(store) and result = asDefinitionImpl(store) and
SsaImpl::defToNode(this, def, _) and Ssa::defToNode(this, def, _) and
if def.isCertain() then uncertain = false else uncertain = true if def.isCertain() then uncertain = false else uncertain = true
) )
} }
@@ -628,7 +627,7 @@ class OperandNode extends Node, Node0 {
* For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`. * For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`.
*/ */
Type stripPointer(Type t) { Type stripPointer(Type t) {
result = any(SsaImpl::Indirection ind | ind.getType() = t).getBaseType() result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType()
or or
result = t.(PointerToMemberType).getBaseType() result = t.(PointerToMemberType).getBaseType()
or or
@@ -695,12 +694,12 @@ class PostFieldUpdateNode extends PostUpdateNodeImpl {
* in a data flow graph. * in a data flow graph.
*/ */
class SsaSynthNode extends Node, TSsaSynthNode { class SsaSynthNode extends Node, TSsaSynthNode {
SsaImpl::SynthNode node; Ssa::SynthNode node;
SsaSynthNode() { this = TSsaSynthNode(node) } SsaSynthNode() { this = TSsaSynthNode(node) }
/** Gets the synthesized SSA node associated with this node. */ /** Gets the synthesized SSA node associated with this node. */
SsaImpl::SynthNode getSynthNode() { result = node } Ssa::SynthNode getSynthNode() { result = node }
override DataFlowCallable getEnclosingCallable() { override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction() result.asSourceCallable() = this.getFunction()
@@ -783,12 +782,12 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
* from a function body. * from a function body.
*/ */
class FinalGlobalValue extends Node, TFinalGlobalValue { class FinalGlobalValue extends Node, TFinalGlobalValue {
SsaImpl::GlobalUse globalUse; Ssa::GlobalUse globalUse;
FinalGlobalValue() { this = TFinalGlobalValue(globalUse) } FinalGlobalValue() { this = TFinalGlobalValue(globalUse) }
/** Gets the underlying SSA use. */ /** Gets the underlying SSA use. */
SsaImpl::GlobalUse getGlobalUse() { result = globalUse } Ssa::GlobalUse getGlobalUse() { result = globalUse }
override DataFlowCallable getEnclosingCallable() { override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction() result.asSourceCallable() = this.getFunction()
@@ -815,12 +814,12 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
* a function body. * a function body.
*/ */
class InitialGlobalValue extends Node, TInitialGlobalValue { class InitialGlobalValue extends Node, TInitialGlobalValue {
SsaImpl::GlobalDef globalDef; Ssa::GlobalDef globalDef;
InitialGlobalValue() { this = TInitialGlobalValue(globalDef) } InitialGlobalValue() { this = TInitialGlobalValue(globalDef) }
/** Gets the underlying SSA definition. */ /** Gets the underlying SSA definition. */
SsaImpl::GlobalDef getGlobalDef() { result = globalDef } Ssa::GlobalDef getGlobalDef() { result = globalDef }
override DataFlowCallable getEnclosingCallable() { override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction() result.asSourceCallable() = this.getFunction()
@@ -1289,11 +1288,11 @@ class UninitializedNode extends Node {
LocalVariable v; LocalVariable v;
UninitializedNode() { UninitializedNode() {
exists(SsaImpl::Definition def, SsaImpl::SourceVariable sv | exists(Ssa::Definition def, Ssa::SourceVariable sv |
def.getIndirectionIndex() = 0 and def.getIndirectionIndex() = 0 and
def.getValue().asInstruction() instanceof UninitializedInstruction and def.getValue().asInstruction() instanceof UninitializedInstruction and
SsaImpl::defToNode(this, def, sv) and Ssa::defToNode(this, def, sv) and
v = sv.getBaseVariable().(SsaImpl::BaseIRVariable).getIRVariable().getAst() v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst()
) )
} }
@@ -1723,7 +1722,7 @@ private module Cached {
cached cached
predicate flowsToBackEdge(Node n) { predicate flowsToBackEdge(Node n) {
exists(Node succ, IRBlock bb1, IRBlock bb2 | exists(Node succ, IRBlock bb1, IRBlock bb2 |
SsaImpl::ssaFlow(n, succ) and Ssa::ssaFlow(n, succ) and
bb1 = n.getBasicBlock() and bb1 = n.getBasicBlock() and
bb2 = succ.getBasicBlock() and bb2 = succ.getBasicBlock() and
bb1 != bb2 and bb1 != bb2 and
@@ -1821,7 +1820,7 @@ private module Cached {
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) { predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
( (
// Def-use/Use-use flow // Def-use/Use-use flow
SsaImpl::ssaFlow(nodeFrom, nodeTo) Ssa::ssaFlow(nodeFrom, nodeTo)
or or
IteratorFlow::localFlowStep(nodeFrom, nodeTo) IteratorFlow::localFlowStep(nodeFrom, nodeTo)
or or
@@ -1834,7 +1833,7 @@ private module Cached {
| |
simpleOperandLocalFlowStep(iFrom, opTo) and simpleOperandLocalFlowStep(iFrom, opTo) and
// Omit when the instruction node also represents the operand. // Omit when the instruction node also represents the operand.
not iFrom = SsaImpl::getIRRepresentationOfOperand(opTo) not iFrom = Ssa::getIRRepresentationOfOperand(opTo)
) )
or or
// Indirect operand -> (indirect) instruction flow // Indirect operand -> (indirect) instruction flow
@@ -1907,7 +1906,7 @@ private module Cached {
// We also want a write coming out of an `OutNode` to flow `nodeTo`. // We also want a write coming out of an `OutNode` to flow `nodeTo`.
// This is different from `reverseFlowInstruction` since `nodeFrom` can never // This is different from `reverseFlowInstruction` since `nodeFrom` can never
// be an `OutNode` when it's defined by an instruction. // be an `OutNode` when it's defined by an instruction.
SsaImpl::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex) Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
) )
} }
@@ -2100,7 +2099,7 @@ private newtype TContent =
TFieldContent(Field f, int indirectionIndex) { TFieldContent(Field f, int indirectionIndex) {
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as // the indirection index for field content starts at 1 (because `TFieldContent` is thought of as
// the address of the field, `FieldAddress` in the IR). // the address of the field, `FieldAddress` in the IR).
indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
// Reads and writes of union fields are tracked using `UnionContent`. // Reads and writes of union fields are tracked using `UnionContent`.
not f.getDeclaringType() instanceof Union not f.getDeclaringType() instanceof Union
} or } or
@@ -2112,9 +2111,7 @@ private newtype TContent =
// field can be read by any read of the union's fields. Again, the indirection index // field can be read by any read of the union's fields. Again, the indirection index
// is 1-based (because 0 is considered the address). // is 1-based (because 0 is considered the address).
indirectionIndex = indirectionIndex =
[1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes) [1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
.getUnspecifiedType())
)]
) )
} or } or
TElementContent(int indirectionIndex) { TElementContent(int indirectionIndex) {
@@ -2357,7 +2354,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
controls(g, result, edge) controls(g, result, edge)
) )
or or
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode() result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
} }
/** /**
@@ -2456,7 +2453,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
) )
or or
result = result =
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex) Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
} }
} }
@@ -2493,7 +2490,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
controls(g, result, edge) controls(g, result, edge)
) )
or or
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode() result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
} }
bindingset[value, n] bindingset[value, n]
@@ -2523,7 +2520,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
) )
or or
result = result =
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex) Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
} }
} }
@@ -2579,16 +2576,3 @@ Function getARuntimeTarget(Call call) {
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable() result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
) )
} }
/** A module that provides static single assignment (SSA) information. */
module Ssa {
class Definition = SsaImpl::Definition;
class ExplicitDefinition = SsaImpl::ExplicitDefinition;
class DirectExplicitDefinition = SsaImpl::DirectExplicitDefinition;
class IndirectExplicitDefinition = SsaImpl::IndirectExplicitDefinition;
class PhiNode = SsaImpl::PhiNode;
}

View File

@@ -4,15 +4,15 @@
*/ */
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs private import semmle.code.cpp.ir.dataflow.DataFlow
private import DataFlowUtil private import DataFlowUtil
private import DataFlowPrivate private import DataFlowPrivate
private import SsaImpl as Ssa private import SsaInternals as Ssa
/** /**
* Gets the instruction that goes into `input` for `call`. * Gets the instruction that goes into `input` for `call`.
*/ */
Node callInput(CallInstruction call, FunctionInput input) { DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
// An argument or qualifier // An argument or qualifier
exists(int index | exists(int index |
result.asOperand() = call.getArgumentOperand(index) and result.asOperand() = call.getArgumentOperand(index) and
@@ -62,8 +62,8 @@ Node callOutput(CallInstruction call, FunctionOutput output) {
result = callOutputWithIndirectionIndex(call, output, _) result = callOutputWithIndirectionIndex(call, output, _)
} }
Node callInput(CallInstruction call, FunctionInput input, int d) { DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
exists(Node n | n = callInput(call, input) and d > 0 | exists(DataFlow::Node n | n = callInput(call, input) and d > 0 |
// An argument or qualifier // An argument or qualifier
hasOperandAndIndex(result, n.asOperand(), d) hasOperandAndIndex(result, n.asOperand(), d)
or or
@@ -85,7 +85,7 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
*/ */
bindingset[d] bindingset[d]
Node callOutput(CallInstruction call, FunctionOutput output, int d) { Node callOutput(CallInstruction call, FunctionOutput output, int d) {
exists(Node n, int indirectionIndex | exists(DataFlow::Node n, int indirectionIndex |
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0 n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
| |
// The return value // The return value

View File

@@ -1,6 +1,6 @@
private import cpp private import cpp
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import SsaImpl as Ssa private import SsaInternals as Ssa
/** /**
* A property provider that hides all instructions and operands that are not relevant for IR dataflow. * A property provider that hides all instructions and operands that are not relevant for IR dataflow.

View File

@@ -2,7 +2,7 @@ private import cpp
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import SsaImpl as Ssa private import SsaInternals as Ssa
private import PrintIRUtilities private import PrintIRUtilities
/** /**

View File

@@ -1,4 +1,4 @@
private import codeql.ssa.Ssa as Ssa private import codeql.ssa.Ssa as SsaImplCommon
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import DataFlowUtil private import DataFlowUtil
private import DataFlowImplCommon as DataFlowImplCommon private import DataFlowImplCommon as DataFlowImplCommon
@@ -12,7 +12,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization
private import DataFlowPrivate private import DataFlowPrivate
import SsaImplCommon import SsaInternalsCommon
private module SourceVariables { private module SourceVariables {
cached cached
@@ -884,7 +884,7 @@ private predicate baseSourceVariableIsGlobal(
) )
} }
private module SsaInput implements Ssa::InputSig<Location> { private module SsaInput implements SsaImplCommon::InputSig<Location> {
import InputSigCommon import InputSigCommon
import SourceVariables import SourceVariables
@@ -958,11 +958,9 @@ class GlobalDef extends Definition {
GlobalLikeVariable getVariable() { result = impl.getVariable() } GlobalLikeVariable getVariable() { result = impl.getVariable() }
} }
private module SsaImpl = Ssa::Make<Location, SsaInput>; private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig { private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
private import codeql.util.Boolean
class Expr extends Instruction { class Expr extends Instruction {
Expr() { Expr() {
exists(IRBlock bb, int i | exists(IRBlock bb, int i |
@@ -994,14 +992,10 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
result instanceof FalseEdge result instanceof FalseEdge
} }
class GuardValue = Boolean;
class Guard instanceof IRGuards::IRGuardCondition { class Guard instanceof IRGuards::IRGuardCondition {
string toString() { result = super.toString() } string toString() { result = super.toString() }
predicate hasValueBranchEdge( predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
) {
exists(EdgeKind kind | exists(EdgeKind kind |
super.getBlock() = bb1 and super.getBlock() = bb1 and
kind = getConditionalEdge(branch) and kind = getConditionalEdge(branch) and
@@ -1009,14 +1003,12 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
) )
} }
predicate valueControlsBranchEdge( predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch this.hasBranchEdge(bb1, bb2, branch)
) {
this.hasValueBranchEdge(bb1, bb2, branch)
} }
} }
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) { predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch) guard.(IRGuards::IRGuardCondition).controls(bb, branch)
} }
@@ -1045,8 +1037,7 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
} }
private predicate guardChecks( private predicate guardChecks(
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, boolean branch, int indirectionIndex
DataFlowIntegrationInput::GuardValue branch, int indirectionIndex
) { ) {
exists(UseImpl use | exists(UseImpl use |
guardChecksNode(g, use.getNode(), branch, indirectionIndex) and guardChecksNode(g, use.getNode(), branch, indirectionIndex) and
@@ -1125,11 +1116,9 @@ class PhiNode extends Definition instanceof SsaImpl::PhiNode {
/** An static single assignment (SSA) definition. */ /** An static single assignment (SSA) definition. */
class Definition extends SsaImpl::Definition { class Definition extends SsaImpl::Definition {
private Definition getAPhiInputOrPriorDefinition() { // TODO: Include prior definitions of uncertain writes or rename predicate
result = this.(PhiNode).getAnInput() // i.e. the disjunct `SsaImpl::uncertainWriteDefinitionInput(this, result)`
or private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
SsaImpl::uncertainWriteDefinitionInput(this, result)
}
/** /**
* Gets a definition that ultimately defines this SSA definition and is * Gets a definition that ultimately defines this SSA definition and is
@@ -1140,36 +1129,6 @@ class Definition extends SsaImpl::Definition {
not result instanceof PhiNode not result instanceof PhiNode
} }
/** Gets an `Operand` that represents a use of this definition. */
Operand getAUse() {
exists(SourceVariable sv, IRBlock bb, int i, UseImpl use |
ssaDefReachesRead(sv, this, bb, i) and
use.hasIndexInBlock(bb, i, sv) and
result = use.getNode().asOperand()
)
}
/**
* Gets an `Operand` that represents an indirect use of this definition.
*
* The use is indirect because the operand represents a pointer that points
* to the value written by this definition. For example in:
* ```cpp
* 1. int x = 42;
* 2. int* p = &x;
* ```
* There is an `ExplicitDefinition` corresponding to `x = 42` on line 1 and
* the definition has an indirect use on line 2 because `&x` points to the
* value that was defined by the definition.
*/
Operand getAnIndirectUse(int indirectionIndex) {
exists(SourceVariable sv, IRBlock bb, int i, UseImpl use |
ssaDefReachesRead(sv, this, bb, i) and
use.hasIndexInBlock(bb, i, sv) and
result = use.getNode().asIndirectOperand(indirectionIndex)
)
}
/** /**
* INTERNAL: Do not use. * INTERNAL: Do not use.
*/ */
@@ -1202,63 +1161,4 @@ class Definition extends SsaImpl::Definition {
Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() } Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() }
} }
/**
* An SSA definition that corresponds to an explicit definition.
*/
class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition {
DefImpl def;
ExplicitDefinition() {
exists(IRBlock bb, int i, SourceVariable sv |
this.definesAt(sv, bb, i) and
def.hasIndexInBlock(sv, bb, i)
)
}
/**
* Gets the `Instruction` computing the value that is written to the
* associated SSA variable by this SSA definition.
*
* If `this.getIndirectionIndex() = 0` (i.e., if `this` is an instance of
* `DirectExplicitDefinition`) then the SSA variable is present in the source
* code.
* However, if `this.getIndirectionIndex() > 0` (i.e., if `this` is an
* instance of `IndirectExplicitDefinition`) then the SSA variable associated
* with this definition represents the memory pointed to by a variable in the
* source code.
*/
Instruction getAssignedInstruction() { result = def.getValue().asInstruction() }
}
/**
* An explicit SSA definition that writes an indirect value to a pointer.
*
* For example in:
* ```cpp
* int x = 42; // (1)
* int* p = &x; // (2)
* ```
* There are three `ExplicitDefinition`:
* 1. A `DirectExplicitDefinition` at (1) which writes `42` to the SSA variable
* corresponding to `x`.
* 2. A `DirectExplicitDefinition` at (2) which writes `&x` to the SSA variable
* corresponding to `p`.
* 3. A `IndirectExplicitDefinition` at (2) which writes `*&x` (i.e., `x`) to
* the SSA variable corresponding to `*p`.
*/
class IndirectExplicitDefinition extends ExplicitDefinition {
IndirectExplicitDefinition() { this.getIndirectionIndex() > 0 }
}
/**
* An SSA definition that corresponds to an explicit definition.
*
* Unlike `ExplicitDefinition` this class does not include indirect
* explicit definition. See `IndirectExplicitDefinition` if you want to include
* those.
*/
class DirectExplicitDefinition extends ExplicitDefinition {
DirectExplicitDefinition() { this.getIndirectionIndex() = 0 }
}
import SsaCached import SsaCached

View File

@@ -5,7 +5,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.SideEffect private import semmle.code.cpp.models.interfaces.SideEffect
private import DataFlowUtil private import DataFlowUtil
private import DataFlowPrivate private import DataFlowPrivate
private import SsaImpl as Ssa private import SsaInternals as Ssa
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.cpp.ir.dataflow.FlowSteps private import semmle.code.cpp.ir.dataflow.FlowSteps

View File

@@ -1,9 +1,3 @@
## 1.4.5
### Minor Analysis Improvements
* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference.
## 1.4.4 ## 1.4.4
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -32,18 +32,9 @@ predicate called(Function f) {
exists(FunctionAccess fa | fa.getTarget() = f) exists(FunctionAccess fa | fa.getTarget() = f)
} }
predicate staticWithoutDereference(GlobalVariable v) {
v.isStatic() and
not exists(VariableAccess va |
va = v.getAnAccess() and
dereferenced(va)
)
}
from GlobalVariable v from GlobalVariable v
where where
global(v) and global(v) and
not staticWithoutDereference(v) and
not exists(VariableAccess lval | not exists(VariableAccess lval |
v.getAnAccess() = lval and v.getAnAccess() = lval and
lval.isUsedAsLValue() and lval.isUsedAsLValue() and

View File

@@ -1,5 +0,0 @@
## 1.4.5
### Minor Analysis Improvements
* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.4.5 lastReleaseVersion: 1.4.4

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries name: codeql/cpp-queries
version: 1.4.5 version: 1.4.5-dev
groups: groups:
- cpp - cpp
- queries - queries

View File

@@ -1,2 +0,0 @@
| test.cpp:12:16:12:17 | g1 | Initialization code for 'g1' is never run. |
| test.cpp:14:23:14:24 | g3 | Initialization code for 'g3' is never run. |

View File

@@ -1 +0,0 @@
Critical/InitialisationNotRun.ql

View File

@@ -1,36 +0,0 @@
// --- stubs ---
char *strcpy(char *dest, const char *src);
// --- tests ---
class GlobalStorage {
public:
char name[1000];
};
GlobalStorage *g1; // BAD
static GlobalStorage g2; // GOOD
static GlobalStorage *g3; // BAD
// static variables are initialized by compilers
static int a; // GOOD
static int b = 0; // GOOD
void init() { //initializes g_storage, but is never run from main
g1 = new GlobalStorage();
g3 = new GlobalStorage();
}
void init2(int b) {
for (int i = 0; i < b; ++i)
a *= -1;
}
int main(int argc, char *argv[]) {
//init not called
strcpy(g1->name, argv[1]); // g1 is used before init() is called
strcpy(g2.name, argv[1]); // g2 is initialised by compiler
strcpy(g3->name, argv[1]);
b++;
return 0;
}

View File

@@ -1,7 +1,3 @@
## 1.7.45
No user-facing changes.
## 1.7.44 ## 1.7.44
No user-facing changes. No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.7.45
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.7.45 lastReleaseVersion: 1.7.44

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all name: codeql/csharp-solorigate-all
version: 1.7.45 version: 1.7.45-dev
groups: groups:
- csharp - csharp
- solorigate - solorigate

View File

@@ -1,7 +1,3 @@
## 1.7.45
No user-facing changes.
## 1.7.44 ## 1.7.44
No user-facing changes. No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.7.45
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.7.45 lastReleaseVersion: 1.7.44

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries name: codeql/csharp-solorigate-queries
version: 1.7.45 version: 1.7.45-dev
groups: groups:
- csharp - csharp
- solorigate - solorigate

View File

@@ -1,7 +1,3 @@
## 5.2.1
No user-facing changes.
## 5.2.0 ## 5.2.0
### New Features ### New Features

View File

@@ -1,3 +0,0 @@
## 5.2.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 5.2.1 lastReleaseVersion: 5.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all name: codeql/csharp-all
version: 5.2.1 version: 5.2.1-dev
groups: csharp groups: csharp
dbscheme: semmlecode.csharp.dbscheme dbscheme: semmlecode.csharp.dbscheme
extractor: csharp extractor: csharp

View File

@@ -975,8 +975,7 @@ private module Cached {
cached // nothing is actually cached cached // nothing is actually cached
module BarrierGuard<guardChecksSig/3 guardChecks> { module BarrierGuard<guardChecksSig/3 guardChecks> {
private predicate guardChecksAdjTypes( private predicate guardChecksAdjTypes(
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
DataFlowIntegrationInput::GuardValue branch
) { ) {
exists(Guards::AbstractValues::BooleanValue v | exists(Guards::AbstractValues::BooleanValue v |
guardChecks(g, e.getAstNode(), v) and guardChecks(g, e.getAstNode(), v) and
@@ -1017,7 +1016,6 @@ string getToStringPrefix(Definition def) {
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig { private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
private import csharp as Cs private import csharp as Cs
private import semmle.code.csharp.controlflow.BasicBlocks private import semmle.code.csharp.controlflow.BasicBlocks
private import codeql.util.Boolean
class Expr extends ControlFlow::Node { class Expr extends ControlFlow::Node {
predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) { this = bb.getNode(i) } predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) { this = bb.getNode(i) }
@@ -1044,14 +1042,12 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
) )
} }
class GuardValue = Boolean;
class Guard extends Guards::Guard { class Guard extends Guards::Guard {
/** /**
* Holds if the evaluation of this guard to `branch` corresponds to the edge * Holds if the evaluation of this guard to `branch` corresponds to the edge
* from `bb1` to `bb2`. * from `bb1` to `bb2`.
*/ */
predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) { predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s | exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s |
this.getAControlFlowNode() = bb1.getLastNode() and this.getAControlFlowNode() = bb1.getLastNode() and
bb2 = bb1.getASuccessorByType(s) and bb2 = bb1.getASuccessorByType(s) and
@@ -1064,13 +1060,13 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
* branch edge from `bb1` to `bb2`. That is, following the edge from * branch edge from `bb1` to `bb2`. That is, following the edge from
* `bb1` to `bb2` implies that this guard evaluated to `branch`. * `bb1` to `bb2` implies that this guard evaluated to `branch`.
*/ */
predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) { predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
this.hasValueBranchEdge(bb1, bb2, branch) this.hasBranchEdge(bb1, bb2, branch)
} }
} }
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */ /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, GuardValue branch) { predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s | exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |
guard.getAControlFlowNode() = conditionBlock.getLastNode() and guard.getAControlFlowNode() = conditionBlock.getLastNode() and
s.getValue() = branch and s.getValue() = branch and

View File

@@ -1,7 +1,3 @@
## 1.3.2
No user-facing changes.
## 1.3.1 ## 1.3.1
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,3 +0,0 @@
## 1.3.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.3.2 lastReleaseVersion: 1.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries name: codeql/csharp-queries
version: 1.3.2 version: 1.3.2-dev
groups: groups:
- csharp - csharp
- queries - queries

View File

@@ -1,7 +1,3 @@
## 1.0.28
No user-facing changes.
## 1.0.27 ## 1.0.27
No user-facing changes. No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.0.28
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.0.28 lastReleaseVersion: 1.0.27

View File

@@ -1,5 +1,5 @@
name: codeql-go-consistency-queries name: codeql-go-consistency-queries
version: 1.0.28 version: 1.0.28-dev
groups: groups:
- go - go
- queries - queries

View File

@@ -1,7 +1,3 @@
## 4.3.1
No user-facing changes.
## 4.3.0 ## 4.3.0
### Deprecated APIs ### Deprecated APIs

View File

@@ -1,3 +0,0 @@
## 4.3.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 4.3.1 lastReleaseVersion: 4.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/go-all name: codeql/go-all
version: 4.3.1 version: 4.3.1-dev
groups: go groups: go
dbscheme: go.dbscheme dbscheme: go.dbscheme
extractor: go extractor: go

View File

@@ -1,7 +1,3 @@
## 1.4.2
No user-facing changes.
## 1.4.1 ## 1.4.1
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,3 +0,0 @@
## 1.4.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.4.2 lastReleaseVersion: 1.4.1

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries name: codeql/go-queries
version: 1.4.2 version: 1.4.2-dev
groups: groups:
- go - go
- queries - queries

BIN
java/kotlin-extractor/deps/kotlin-compiler-2.2.20-Beta1.jar (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.2.20-Beta1.jar (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -12,7 +12,7 @@ VERSIONS = [
"2.1.0-Beta1", "2.1.0-Beta1",
"2.1.20-Beta1", "2.1.20-Beta1",
"2.2.0-Beta1", "2.2.0-Beta1",
"2.2.20-Beta2", "2.2.20-Beta1",
] ]
def _version_to_tuple(v): def _version_to_tuple(v):

View File

@@ -1,9 +1,3 @@
## 7.5.0
### New Features
* Kotlin versions up to 2.2.2\ *x* are now supported.
## 7.4.0 ## 7.4.0
### Deprecated APIs ### Deprecated APIs
@@ -16,7 +10,7 @@
### New Features ### New Features
* You can now add sinks for the query "Deserialization of user-controlled data" (`java/unsafe-deserialization`) using [data extensions](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/#extensible-predicates-used-to-create-custom-models-in-java-and-kotlin) by extending `sinkModel` and using the kind "unsafe-deserialization". The existing sinks that do not require extra logic to determine if they are unsafe are now defined in this way. * You can now add sinks for the query "Deserialization of user-controlled data" (`java/unsafe-deserialization`) using [data extensions](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/#extensible-predicates-used-to-create-custom-models-in-java-and-kotlin) by extending `sinkModel` and using the kind "unsafe-deserialization". The existing sinks which do not require extra logic to determine if they are unsafe are now defined in this way.
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,5 +1,4 @@
## 7.5.0 ---
category: feature
### New Features ---
* Kotlin versions up to 2.2.2\ *x* are now supported. * Kotlin versions up to 2.2.2\ *x* are now supported.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 7.5.0 lastReleaseVersion: 7.4.0

View File

@@ -1,5 +1,5 @@
name: codeql/java-all name: codeql/java-all
version: 7.5.0 version: 7.4.1-dev
groups: java groups: java
dbscheme: config/semmlecode.dbscheme dbscheme: config/semmlecode.dbscheme
extractor: java extractor: java

View File

@@ -563,9 +563,9 @@ private module Cached {
cached // nothing is actually cached cached // nothing is actually cached
module BarrierGuard<guardChecksSig/3 guardChecks> { module BarrierGuard<guardChecksSig/3 guardChecks> {
private predicate guardChecksAdjTypes( private predicate guardChecksAdjTypes(
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, Guards::GuardValue val DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
) { ) {
guardChecks(g, e, val.asBooleanValue()) guardChecks(g, e, branch)
} }
private Node getABarrierNodeImpl() { private Node getABarrierNodeImpl() {
@@ -657,18 +657,16 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
def instanceof SsaUncertainImplicitUpdate def instanceof SsaUncertainImplicitUpdate
} }
class GuardValue = Guards::GuardValue;
class Guard = Guards::Guard; class Guard = Guards::Guard;
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `val`. */ /** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) { predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.directlyValueControls(bb, val) guard.directlyControls(bb, branch)
} }
/** Holds if the guard `guard` controls block `bb` upon evaluating to `val`. */ /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, BasicBlock bb, GuardValue val) { predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.valueControls(bb, val) guard.controls(bb, branch)
} }
predicate includeWriteDefsInFlowStep() { none() } predicate includeWriteDefsInFlowStep() { none() }

View File

@@ -1,7 +1,3 @@
## 1.6.2
No user-facing changes.
## 1.6.1 ## 1.6.1
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,3 +0,0 @@
## 1.6.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.6.2 lastReleaseVersion: 1.6.1

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries name: codeql/java-queries
version: 1.6.2 version: 1.6.2-dev
groups: groups:
- java - java
- queries - queries

View File

@@ -83,5 +83,6 @@ ql/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql
ql/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql ql/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql
ql/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql ql/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql
ql/javascript/ql/src/Security/CWE-918/RequestForgery.ql ql/javascript/ql/src/Security/CWE-918/RequestForgery.ql
ql/javascript/ql/src/Security/CWE-942/CorsPermissiveConfiguration.ql
ql/javascript/ql/src/Summary/LinesOfCode.ql ql/javascript/ql/src/Summary/LinesOfCode.ql
ql/javascript/ql/src/Summary/LinesOfUserCode.ql ql/javascript/ql/src/Summary/LinesOfUserCode.ql

View File

@@ -184,6 +184,7 @@ ql/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql
ql/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql ql/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql
ql/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql ql/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql
ql/javascript/ql/src/Security/CWE-918/RequestForgery.ql ql/javascript/ql/src/Security/CWE-918/RequestForgery.ql
ql/javascript/ql/src/Security/CWE-942/CorsPermissiveConfiguration.ql
ql/javascript/ql/src/Statements/DanglingElse.ql ql/javascript/ql/src/Statements/DanglingElse.ql
ql/javascript/ql/src/Statements/IgnoreArrayResult.ql ql/javascript/ql/src/Statements/IgnoreArrayResult.ql
ql/javascript/ql/src/Statements/InconsistentLoopOrientation.ql ql/javascript/ql/src/Statements/InconsistentLoopOrientation.ql

View File

@@ -99,5 +99,6 @@ ql/javascript/ql/src/Security/CWE-915/PrototypePollutingMergeCall.ql
ql/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql ql/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.ql
ql/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql ql/javascript/ql/src/Security/CWE-918/ClientSideRequestForgery.ql
ql/javascript/ql/src/Security/CWE-918/RequestForgery.ql ql/javascript/ql/src/Security/CWE-918/RequestForgery.ql
ql/javascript/ql/src/Security/CWE-942/CorsPermissiveConfiguration.ql
ql/javascript/ql/src/Summary/LinesOfCode.ql ql/javascript/ql/src/Summary/LinesOfCode.ql
ql/javascript/ql/src/Summary/LinesOfUserCode.ql ql/javascript/ql/src/Summary/LinesOfUserCode.ql

View File

@@ -75,7 +75,6 @@ ql/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerificationL
ql/javascript/ql/src/experimental/Security/CWE-444/InsecureHttpParser.ql ql/javascript/ql/src/experimental/Security/CWE-444/InsecureHttpParser.ql
ql/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql ql/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql
ql/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql ql/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql
ql/javascript/ql/src/experimental/Security/CWE-942/CorsPermissiveConfiguration.ql
ql/javascript/ql/src/experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql ql/javascript/ql/src/experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql
ql/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql ql/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql
ql/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql ql/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql

View File

@@ -1,9 +1,3 @@
## 2.6.8
### Minor Analysis Improvements
* The regular expressions in `SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information.
## 2.6.7 ## 2.6.7
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,5 +1,4 @@
## 2.6.8 ---
category: minorAnalysis
### Minor Analysis Improvements ---
* The regular expressions in `SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. * The regular expressions in `SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 2.6.8 lastReleaseVersion: 2.6.7

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all name: codeql/javascript-all
version: 2.6.8 version: 2.6.8-dev
groups: javascript groups: javascript
dbscheme: semmlecode.javascript.dbscheme dbscheme: semmlecode.javascript.dbscheme
extractor: javascript extractor: javascript

View File

@@ -193,8 +193,6 @@ private module ConditionGuardDominators {
module MakeStateBarrierGuard< module MakeStateBarrierGuard<
FlowStateSig FlowState, WithFlowState<FlowState>::BarrierGuardSig BaseGuard> FlowStateSig FlowState, WithFlowState<FlowState>::BarrierGuardSig BaseGuard>
{ {
private import codeql.util.Boolean
final private class FinalNode = DataFlow::Node; final private class FinalNode = DataFlow::Node;
abstract private class BarrierGuard extends FinalNode { abstract private class BarrierGuard extends FinalNode {
@@ -297,7 +295,7 @@ module MakeStateBarrierGuard<
} }
private predicate ssa2GuardChecks( private predicate ssa2GuardChecks(
Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, Boolean branch, Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, boolean branch,
FlowState state FlowState state
) { ) {
exists(BarrierGuard g | exists(BarrierGuard g |

View File

@@ -6,7 +6,6 @@ private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as
private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate
private import semmle.javascript.dataflow.internal.BarrierGuards private import semmle.javascript.dataflow.internal.BarrierGuards
private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2
private import codeql.util.Boolean
cached cached
predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
@@ -38,7 +37,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2,
} }
private predicate guardChecksFalsy( private predicate guardChecksFalsy(
Ssa2::SsaDataflowInput::Guard g, Ssa2::SsaDataflowInput::Expr e, Boolean outcome Ssa2::SsaDataflowInput::Guard g, Ssa2::SsaDataflowInput::Expr e, boolean outcome
) { ) {
exists(ConditionGuardNode guard | exists(ConditionGuardNode guard |
guard.getTest() = g and guard.getTest() = g and

View File

@@ -50,8 +50,6 @@ module SsaConfig implements InputSig<js::DbLocation> {
import Make<js::DbLocation, SsaConfig> import Make<js::DbLocation, SsaConfig>
module SsaDataflowInput implements DataFlowIntegrationInputSig { module SsaDataflowInput implements DataFlowIntegrationInputSig {
private import codeql.util.Boolean
class Expr extends js::ControlFlowNode { class Expr extends js::ControlFlowNode {
Expr() { this = any(SsaConfig::SourceVariable v).getAUse() } Expr() { this = any(SsaConfig::SourceVariable v).getAUse() }
@@ -73,8 +71,6 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
) )
} }
class GuardValue = Boolean;
class Guard extends js::ControlFlowNode { class Guard extends js::ControlFlowNode {
Guard() { this = any(js::ConditionGuardNode g).getTest() } Guard() { this = any(js::ConditionGuardNode g).getTest() }
@@ -82,7 +78,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
* Holds if the evaluation of this guard to `branch` corresponds to the edge * Holds if the evaluation of this guard to `branch` corresponds to the edge
* from `bb1` to `bb2`. * from `bb1` to `bb2`.
*/ */
predicate hasValueBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, GuardValue branch) { predicate hasBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) {
exists(js::ConditionGuardNode g | exists(js::ConditionGuardNode g |
g.getTest() = this and g.getTest() = this and
bb1 = this.getBasicBlock() and bb1 = this.getBasicBlock() and
@@ -96,13 +92,13 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
* branch edge from `bb1` to `bb2`. That is, following the edge from * branch edge from `bb1` to `bb2`. That is, following the edge from
* `bb1` to `bb2` implies that this guard evaluated to `branch`. * `bb1` to `bb2` implies that this guard evaluated to `branch`.
*/ */
predicate valueControlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, GuardValue branch) { predicate controlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) {
this.hasValueBranchEdge(bb1, bb2, branch) this.hasBranchEdge(bb1, bb2, branch)
} }
} }
pragma[inline] pragma[inline]
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, GuardValue branch) { predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
exists(js::ConditionGuardNode g | exists(js::ConditionGuardNode g |
g.getTest() = guard and g.getTest() = guard and
g.dominates(bb) and g.dominates(bb) and

View File

@@ -5,8 +5,8 @@
*/ */
import javascript import javascript
import Cors::Cors private import semmle.javascript.frameworks.Apollo
import Apollo::Apollo private import semmle.javascript.frameworks.Cors
/** Module containing sources, sinks, and sanitizers for overly permissive CORS configurations. */ /** Module containing sources, sinks, and sanitizers for overly permissive CORS configurations. */
module CorsPermissiveConfiguration { module CorsPermissiveConfiguration {
@@ -26,6 +26,7 @@ module CorsPermissiveConfiguration {
this = TWildcard() and result = "wildcard" this = TWildcard() and result = "wildcard"
} }
/** DEPRECATED: Converts this flow state to a flow label. */
deprecated DataFlow::FlowLabel toFlowLabel() { deprecated DataFlow::FlowLabel toFlowLabel() {
this = TTaint() and result.isTaint() this = TTaint() and result.isTaint()
or or
@@ -37,6 +38,7 @@ module CorsPermissiveConfiguration {
/** Predicates for working with flow states. */ /** Predicates for working with flow states. */
module FlowState { module FlowState {
/** DEPRECATED: Gets a flow state from a flow label. */
deprecated FlowState fromFlowLabel(DataFlow::FlowLabel label) { result.toFlowLabel() = label } deprecated FlowState fromFlowLabel(DataFlow::FlowLabel label) { result.toFlowLabel() = label }
/** A tainted value. */ /** A tainted value. */
@@ -81,6 +83,7 @@ module CorsPermissiveConfiguration {
TrueAndNull() { this = "TrueAndNull" } TrueAndNull() { this = "TrueAndNull" }
} }
/** DEPRECATED: Gets a flow label representing `true` and `null` values. */
deprecated TrueAndNull truenullLabel() { any() } deprecated TrueAndNull truenullLabel() { any() }
/** A flow label representing `*` value. */ /** A flow label representing `*` value. */
@@ -88,6 +91,7 @@ module CorsPermissiveConfiguration {
Wildcard() { this = "Wildcard" } Wildcard() { this = "Wildcard" }
} }
/** DEPRECATED: Gets a flow label representing `*` value. */
deprecated Wildcard wildcardLabel() { any() } deprecated Wildcard wildcardLabel() { any() }
/** An overly permissive value for `origin` (Apollo) */ /** An overly permissive value for `origin` (Apollo) */
@@ -105,7 +109,7 @@ module CorsPermissiveConfiguration {
*/ */
class CorsApolloServer extends Sink, DataFlow::ValueNode { class CorsApolloServer extends Sink, DataFlow::ValueNode {
CorsApolloServer() { CorsApolloServer() {
exists(ApolloServer agql | exists(Apollo::ApolloServer agql |
this = this =
agql.getOptionArgument(0, "cors").getALocalSource().getAPropertyWrite("origin").getRhs() agql.getOptionArgument(0, "cors").getALocalSource().getAPropertyWrite("origin").getRhs()
) )
@@ -125,7 +129,7 @@ module CorsPermissiveConfiguration {
* An express route setup configured with the `cors` package. * An express route setup configured with the `cors` package.
*/ */
class CorsConfiguration extends DataFlow::MethodCallNode { class CorsConfiguration extends DataFlow::MethodCallNode {
Cors corsConfig; Cors::Cors corsConfig;
CorsConfiguration() { CorsConfiguration() {
exists(Express::RouteSetup setup | this = setup | exists(Express::RouteSetup setup | this = setup |
@@ -136,6 +140,6 @@ module CorsPermissiveConfiguration {
} }
/** Gets the expression that configures `cors` on this route setup. */ /** Gets the expression that configures `cors` on this route setup. */
Cors getCorsConfiguration() { result = corsConfig } Cors::Cors getCorsConfiguration() { result = corsConfig }
} }
} }

View File

@@ -1,7 +1,3 @@
## 2.0.1
No user-facing changes.
## 2.0.0 ## 2.0.0
### Breaking Changes ### Breaking Changes

View File

@@ -1,5 +1,5 @@
/** /**
* @name overly CORS configuration * @name Permissive CORS configuration
* @description Misconfiguration of CORS HTTP headers allows CSRF attacks. * @description Misconfiguration of CORS HTTP headers allows CSRF attacks.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
@@ -11,11 +11,12 @@
*/ */
import javascript import javascript
import CorsPermissiveConfigurationQuery import semmle.javascript.security.CorsPermissiveConfigurationQuery as CorsQuery
import CorsPermissiveConfigurationFlow::PathGraph import CorsQuery::CorsPermissiveConfigurationFlow::PathGraph
from from
CorsPermissiveConfigurationFlow::PathNode source, CorsPermissiveConfigurationFlow::PathNode sink CorsQuery::CorsPermissiveConfigurationFlow::PathNode source,
where CorsPermissiveConfigurationFlow::flowPath(source, sink) CorsQuery::CorsPermissiveConfigurationFlow::PathNode sink
where CorsQuery::CorsPermissiveConfigurationFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "CORS Origin misconfiguration due to a $@.", source.getNode(), select sink.getNode(), source, sink, "CORS Origin misconfiguration due to a $@.", source.getNode(),
"too permissive or user controlled value" "too permissive or user controlled value"

View File

@@ -1,3 +0,0 @@
## 2.0.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 2.0.1 lastReleaseVersion: 2.0.0

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