mirror of
https://github.com/github/codeql.git
synced 2026-05-20 22:27:18 +02:00
Compare commits
160 Commits
alexdeniso
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff65ffafb0 | ||
|
|
97402fdf36 | ||
|
|
2662a4c651 | ||
|
|
dce03569e5 | ||
|
|
6ec9b95072 | ||
|
|
641646ac08 | ||
|
|
75f42f4614 | ||
|
|
0c1fb8c881 | ||
|
|
4f9303eb02 | ||
|
|
2c23dacca1 | ||
|
|
de83929a60 | ||
|
|
f1001374fd | ||
|
|
25d3af9236 | ||
|
|
1f3f1b5ec4 | ||
|
|
5c0fb2030d | ||
|
|
71ef98584d | ||
|
|
6bba191407 | ||
|
|
df144f3a1e | ||
|
|
a46dc55e84 | ||
|
|
14268f3c63 | ||
|
|
408ba517e5 | ||
|
|
4d4ca6b948 | ||
|
|
d443354651 | ||
|
|
57f6859ddc | ||
|
|
5f087f0084 | ||
|
|
f66f7ce8d7 | ||
|
|
f22979f4b6 | ||
|
|
46e6e72593 | ||
|
|
92c18960c5 | ||
|
|
e349891cff | ||
|
|
e02c32f3d4 | ||
|
|
0f1dc9b2d9 | ||
|
|
ae6c95ff95 | ||
|
|
bae7e10e46 | ||
|
|
ec63099c54 | ||
|
|
2b8b5cf1b8 | ||
|
|
6730f57d5c | ||
|
|
118d50236f | ||
|
|
7a001f4905 | ||
|
|
803ed20962 | ||
|
|
4256fbf11a | ||
|
|
f3dd002ba9 | ||
|
|
f9e9ae91f7 | ||
|
|
23419ee634 | ||
|
|
b8f0f85840 | ||
|
|
69453aa144 | ||
|
|
55f5b26ba6 | ||
|
|
721bde1ce8 | ||
|
|
2e9d548083 | ||
|
|
83d1fc33e1 | ||
|
|
14e51627c5 | ||
|
|
52540b42fc | ||
|
|
6bd7047e41 | ||
|
|
57f1f5b829 | ||
|
|
bff93c4484 | ||
|
|
0342b3eba2 | ||
|
|
d28e7920b3 | ||
|
|
331ca61be9 | ||
|
|
559b965e74 | ||
|
|
6299b844f8 | ||
|
|
4385b316c0 | ||
|
|
b1dc6099ff | ||
|
|
15099b3db0 | ||
|
|
8334c6db91 | ||
|
|
1c75e5b2a6 | ||
|
|
1623bba18a | ||
|
|
475d8da342 | ||
|
|
ae09499905 | ||
|
|
c950e26b3e | ||
|
|
f75c062949 | ||
|
|
f22d87b7c7 | ||
|
|
e11a68803e | ||
|
|
45faed057c | ||
|
|
f1b67ade9b | ||
|
|
f9ae7c5454 | ||
|
|
296dee90dd | ||
|
|
967bbbc1a7 | ||
|
|
28a5a1d507 | ||
|
|
5b38ba87df | ||
|
|
db42b60015 | ||
|
|
f8c8d59cb5 | ||
|
|
c8779d0d0b | ||
|
|
28160e418c | ||
|
|
ed349f7d6b | ||
|
|
fa569dcef4 | ||
|
|
040d971588 | ||
|
|
e95bfc816e | ||
|
|
44935cef63 | ||
|
|
190050f577 | ||
|
|
458baeff32 | ||
|
|
c14d4042e0 | ||
|
|
5a451e964d | ||
|
|
b157d73c10 | ||
|
|
985d1990eb | ||
|
|
463096e4be | ||
|
|
892beeab6d | ||
|
|
9ec2f9204b | ||
|
|
c73e6f1fa8 | ||
|
|
9aafbfce13 | ||
|
|
cc6268339b | ||
|
|
834b07e6ad | ||
|
|
8be6aeda3e | ||
|
|
359dcf37e9 | ||
|
|
eb263e747f | ||
|
|
bc576f658e | ||
|
|
6f56a656e4 | ||
|
|
ed9a0ea155 | ||
|
|
c3577b34d3 | ||
|
|
e4da8da5d9 | ||
|
|
b455b2c1a6 | ||
|
|
098ea50068 | ||
|
|
6e291711ac | ||
|
|
fca6ccd2f1 | ||
|
|
4bf717c3e4 | ||
|
|
d15c46836b | ||
|
|
d56625cb8b | ||
|
|
c327f0f0a7 | ||
|
|
8f141cb157 | ||
|
|
5a09a325f2 | ||
|
|
5fc8a00487 | ||
|
|
b3feb4d7e9 | ||
|
|
ebf7231be7 | ||
|
|
9b5556e245 | ||
|
|
2d313ef4c7 | ||
|
|
cd147038cd | ||
|
|
a86862d578 | ||
|
|
04016ebd20 | ||
|
|
f99df55e94 | ||
|
|
9b0ad8295e | ||
|
|
9d5cf0b331 | ||
|
|
5433907c33 | ||
|
|
5bee44dcfe | ||
|
|
6568332e3d | ||
|
|
6c50c2bfe6 | ||
|
|
e8eff78799 | ||
|
|
ad756d59c8 | ||
|
|
315bdc2b48 | ||
|
|
637c52d10a | ||
|
|
92b13c4259 | ||
|
|
3d8a7e0ee3 | ||
|
|
57c645bd24 | ||
|
|
1f2e8d898d | ||
|
|
225c96ec9f | ||
|
|
37361d9f79 | ||
|
|
3697ef72c4 | ||
|
|
5cab25662c | ||
|
|
8ed10317bd | ||
|
|
dd9a2db137 | ||
|
|
020b4becfd | ||
|
|
5385cc3aaa | ||
|
|
9087259b1b | ||
|
|
968127eaa3 | ||
|
|
e0782683eb | ||
|
|
dafcd5ec98 | ||
|
|
a0e2e1ef21 | ||
|
|
1fe565a46f | ||
|
|
76e56cdac7 | ||
|
|
ad2631202d | ||
|
|
6c8cc79b4d | ||
|
|
1a51c015b4 |
@@ -145,9 +145,9 @@ namespace Semmle.Autobuild.Cpp.Tests
|
||||
|
||||
bool IBuildActions.IsMacOs() => IsMacOs;
|
||||
|
||||
public bool IsArm { get; set; }
|
||||
public bool IsRunningOnAppleSilicon { get; set; }
|
||||
|
||||
bool IBuildActions.IsArm() => IsArm;
|
||||
bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
|
||||
|
||||
string IBuildActions.PathCombine(params string[] parts)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
## 0.12.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
|
||||
* Added models for `strlcpy` and `strlcat`.
|
||||
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
||||
* Added SQL API models for `ODBC`.
|
||||
* Added taint models for `realloc` and related functions.
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added taint models for `realloc` and related functions.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for `strlcpy` and `strlcat`.
|
||||
13
cpp/ql/lib/change-notes/released/0.12.0.md
Normal file
13
cpp/ql/lib/change-notes/released/0.12.0.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## 0.12.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
|
||||
* Added models for `strlcpy` and `strlcat`.
|
||||
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
||||
* Added SQL API models for `ODBC`.
|
||||
* Added taint models for `realloc` and related functions.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.11.0
|
||||
lastReleaseVersion: 0.12.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.11.1-dev
|
||||
version: 0.12.0
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -27,16 +27,26 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
|
||||
|
||||
override predicate isSource(Instruction source) {
|
||||
// Holds if `source` is a node that represents the use of a stack variable
|
||||
exists(VariableAddressInstruction var, Function func |
|
||||
var = source and
|
||||
func = source.getEnclosingFunction() and
|
||||
var.getAstVariable() instanceof StackVariable and
|
||||
// Pointer-to-member types aren't properly handled in the dbscheme.
|
||||
not var.getResultType() instanceof PointerToMemberType and
|
||||
exists(Function func |
|
||||
// Rule out FPs caused by extraction errors.
|
||||
not any(ErrorExpr e).getEnclosingFunction() = func and
|
||||
not intentionallyReturnsStackPointer(func)
|
||||
not intentionallyReturnsStackPointer(func) and
|
||||
func = source.getEnclosingFunction()
|
||||
|
|
||||
// `source` is an instruction that represents the use of a stack variable
|
||||
exists(VariableAddressInstruction var |
|
||||
var = source and
|
||||
var.getAstVariable() instanceof StackVariable and
|
||||
// Pointer-to-member types aren't properly handled in the dbscheme.
|
||||
not var.getResultType() instanceof PointerToMemberType
|
||||
)
|
||||
or
|
||||
// `source` is an instruction that represents the return value of a
|
||||
// function that is known to return stack-allocated memory.
|
||||
exists(Call call |
|
||||
call.getTarget().hasGlobalName(["alloca", "strdupa", "strndupa", "_alloca", "_malloca"]) and
|
||||
source.getUnconvertedResultExpression() = call
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -85,10 +95,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
}
|
||||
|
||||
from
|
||||
MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var,
|
||||
MustFlowPathNode source, MustFlowPathNode sink, Instruction instr,
|
||||
ReturnStackAllocatedMemoryConfig conf
|
||||
where
|
||||
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
|
||||
source.getInstruction() = var
|
||||
source.getInstruction() = instr
|
||||
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
|
||||
var.getAst(), var.getAst().toString()
|
||||
instr.getAst(), instr.getAst().toString()
|
||||
|
||||
@@ -14,25 +14,47 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
import Flow::PathGraph
|
||||
|
||||
predicate isProcessOperationExplanation(Expr arg, string processOperation) {
|
||||
predicate isProcessOperationExplanation(DataFlow::Node arg, string processOperation) {
|
||||
exists(int processOperationArg, FunctionCall call |
|
||||
isProcessOperationArgument(processOperation, processOperationArg) and
|
||||
call.getTarget().getName() = processOperation and
|
||||
call.getArgument(processOperationArg) = arg
|
||||
call.getArgument(processOperationArg) = [arg.asExpr(), arg.asIndirectExpr()]
|
||||
)
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element arg) { isProcessOperationExplanation(arg, _) }
|
||||
predicate isSource(FlowSource source, string sourceType) {
|
||||
not source instanceof DataFlow::ExprNode and
|
||||
sourceType = source.getSourceType()
|
||||
}
|
||||
|
||||
from string processOperation, Expr arg, Expr source, PathNode sourceNode, PathNode sinkNode
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node node) { isProcessOperationExplanation(node, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from
|
||||
string processOperation, string sourceType, DataFlow::Node source, DataFlow::Node sink,
|
||||
Flow::PathNode sourceNode, Flow::PathNode sinkNode
|
||||
where
|
||||
isProcessOperationExplanation(arg, processOperation) and
|
||||
taintedWithPath(source, arg, sourceNode, sinkNode)
|
||||
select arg, sourceNode, sinkNode,
|
||||
source = sourceNode.getNode() and
|
||||
sink = sinkNode.getNode() and
|
||||
isSource(source, sourceType) and
|
||||
isProcessOperationExplanation(sink, processOperation) and
|
||||
Flow::flowPath(sourceNode, sinkNode)
|
||||
select sink, sourceNode, sinkNode,
|
||||
"The value of this argument may come from $@ and is being passed to " + processOperation + ".",
|
||||
source, source.toString()
|
||||
source, sourceType
|
||||
|
||||
@@ -52,16 +52,17 @@ predicate isUnboundedWrite(BufferWrite bw) {
|
||||
* Holds if `e` is a source buffer going into an unbounded write `bw` or a
|
||||
* qualifier of (a qualifier of ...) such a source.
|
||||
*/
|
||||
predicate unboundedWriteSource(Expr e, BufferWrite bw) {
|
||||
isUnboundedWrite(bw) and e = bw.getASource()
|
||||
predicate unboundedWriteSource(Expr e, BufferWrite bw, boolean qualifier) {
|
||||
isUnboundedWrite(bw) and e = bw.getASource() and qualifier = false
|
||||
or
|
||||
exists(FieldAccess fa | unboundedWriteSource(fa, bw) and e = fa.getQualifier())
|
||||
exists(FieldAccess fa | unboundedWriteSource(fa, bw, _) and e = fa.getQualifier()) and
|
||||
qualifier = true
|
||||
}
|
||||
|
||||
predicate isSource(FS::FlowSource source, string sourceType) { source.getSourceType() = sourceType }
|
||||
|
||||
predicate isSink(DataFlow::Node sink, BufferWrite bw) {
|
||||
unboundedWriteSource(sink.asIndirectExpr(), bw)
|
||||
predicate isSink(DataFlow::Node sink, BufferWrite bw, boolean qualifier) {
|
||||
unboundedWriteSource(sink.asIndirectExpr(), bw, qualifier)
|
||||
or
|
||||
// `gets` and `scanf` reads from stdin so there's no real input.
|
||||
// The `BufferWrite` library models this as the call itself being
|
||||
@@ -69,7 +70,7 @@ predicate isSink(DataFlow::Node sink, BufferWrite bw) {
|
||||
// the sink so that we report a path where source = sink (because
|
||||
// the same output argument is also included in `isSource`).
|
||||
bw.getASource() = bw and
|
||||
unboundedWriteSource(sink.asDefiningArgument(), bw)
|
||||
unboundedWriteSource(sink.asDefiningArgument(), bw, qualifier)
|
||||
}
|
||||
|
||||
predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
|
||||
@@ -84,9 +85,9 @@ predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node node) { isSink(node) }
|
||||
predicate isBarrierOut(DataFlow::Node node) { isSink(node, _, false) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
// Block flow if the node is guarded by any <, <= or = operations.
|
||||
@@ -116,7 +117,7 @@ from BufferWrite bw, Flow::PathNode source, Flow::PathNode sink, string sourceTy
|
||||
where
|
||||
Flow::flowPath(source, sink) and
|
||||
isSource(source.getNode(), sourceType) and
|
||||
isSink(sink.getNode(), bw)
|
||||
isSink(sink.getNode(), bw, _)
|
||||
select bw, source, sink,
|
||||
"This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.",
|
||||
source.getNode(), sourceType
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Overflow
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.controlflow.IRGuards as IRGuards
|
||||
import semmle.code.cpp.security.FlowSources as FS
|
||||
import Bounded
|
||||
import Flow::PathGraph
|
||||
|
||||
bindingset[op]
|
||||
predicate missingGuard(Operation op, Expr e, string effect) {
|
||||
@@ -28,28 +31,90 @@ predicate missingGuard(Operation op, Expr e, string effect) {
|
||||
not e instanceof VariableAccess and effect = "overflow"
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element e) {
|
||||
exists(Operation op |
|
||||
missingGuard(op, e, _) and
|
||||
op.getAnOperand() = e
|
||||
|
|
||||
op instanceof UnaryArithmeticOperation or
|
||||
op instanceof BinaryArithmeticOperation or
|
||||
op instanceof AssignArithmeticOperation
|
||||
)
|
||||
}
|
||||
predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
|
||||
|
||||
override predicate isBarrier(Expr e) {
|
||||
super.isBarrier(e) or bounded(e) or e.getUnspecifiedType().(IntegralType).getSize() <= 1
|
||||
predicate isSink(DataFlow::Node sink, Operation op, Expr e) {
|
||||
e = sink.asExpr() and
|
||||
missingGuard(op, e, _) and
|
||||
op.getAnOperand() = e and
|
||||
(
|
||||
op instanceof UnaryArithmeticOperation or
|
||||
op instanceof BinaryArithmeticOperation or
|
||||
op instanceof AssignArithmeticOperation
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasUpperBoundsCheck(Variable var) {
|
||||
exists(RelationalOperation oper, VariableAccess access |
|
||||
oper.getAnOperand() = access and
|
||||
access.getTarget() = var and
|
||||
// Comparing to 0 is not an upper bound check
|
||||
not oper.getAnOperand().getValue() = "0"
|
||||
)
|
||||
}
|
||||
|
||||
predicate constantInstruction(Instruction instr) {
|
||||
instr instanceof ConstantInstruction or
|
||||
constantInstruction(instr.(UnaryInstruction).getUnary())
|
||||
}
|
||||
|
||||
predicate readsVariable(LoadInstruction load, Variable var) {
|
||||
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
|
||||
}
|
||||
|
||||
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
|
||||
exists(Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
|
||||
)
|
||||
}
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
exists(StoreInstruction store | store = node.asInstruction() |
|
||||
// Block flow to "likely small expressions"
|
||||
bounded(store.getSourceValue().getUnconvertedResultExpression())
|
||||
or
|
||||
// Block flow to "small types"
|
||||
store.getResultType().getUnspecifiedType().(IntegralType).getSize() <= 1
|
||||
)
|
||||
or
|
||||
// Block flow if there's an upper bound check of the variable anywhere in the program
|
||||
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
hasUpperBoundsCheck(checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow if the node is guarded by an equality check
|
||||
exists(Variable checkedVar, Operand access |
|
||||
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
|
||||
readsVariable(access.getDef(), checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow to any binary instruction whose operands are both non-constants.
|
||||
exists(BinaryInstruction iTo |
|
||||
iTo = node.asInstruction() and
|
||||
not constantInstruction(iTo.getLeft()) and
|
||||
not constantInstruction(iTo.getRight()) and
|
||||
// propagate taint from either the pointer or the offset, regardless of constantness
|
||||
not iTo instanceof PointerArithmeticInstruction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from Expr origin, Expr e, string effect, PathNode sourceNode, PathNode sinkNode, Operation op
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from
|
||||
Expr e, string effect, Flow::PathNode source, Flow::PathNode sink, Operation op, string sourceType
|
||||
where
|
||||
taintedWithPath(origin, e, sourceNode, sinkNode) and
|
||||
op.getAnOperand() = e and
|
||||
Flow::flowPath(source, sink) and
|
||||
isSource(source.getNode(), sourceType) and
|
||||
isSink(sink.getNode(), op, e) and
|
||||
missingGuard(op, e, effect)
|
||||
select e, sourceNode, sinkNode,
|
||||
select e, source, sink,
|
||||
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
|
||||
origin, "User-provided value"
|
||||
source, sourceType
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
|
||||
* @kind metric
|
||||
* @tags summary
|
||||
* telemetry
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added SQL API models for `ODBC`.
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.3
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -43,6 +43,11 @@ edges
|
||||
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) |
|
||||
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) |
|
||||
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) |
|
||||
| test.cpp:237:12:237:17 | call to alloca | test.cpp:237:12:237:17 | call to alloca |
|
||||
| test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:249:13:249:20 | call to strndupa |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | s2 |
|
||||
| test.cpp:250:9:250:10 | s2 | test.cpp:250:9:250:10 | (void *)... |
|
||||
nodes
|
||||
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
|
||||
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
|
||||
@@ -101,6 +106,14 @@ nodes
|
||||
| test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) |
|
||||
| test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) |
|
||||
| test.cpp:190:10:190:13 | pRef | semmle.label | pRef |
|
||||
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
|
||||
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
|
||||
| test.cpp:238:9:238:9 | p | semmle.label | p |
|
||||
| test.cpp:245:9:245:15 | call to strdupa | semmle.label | call to strdupa |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
|
||||
| test.cpp:250:9:250:10 | (void *)... | semmle.label | (void *)... |
|
||||
| test.cpp:250:9:250:10 | s2 | semmle.label | s2 |
|
||||
#select
|
||||
| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
|
||||
| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
|
||||
@@ -115,3 +128,6 @@ nodes
|
||||
| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
|
||||
| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
|
||||
| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |
|
||||
| test.cpp:238:9:238:9 | Load: p | test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p | May return stack-allocated memory from $@. | test.cpp:237:12:237:17 | call to alloca | call to alloca |
|
||||
| test.cpp:245:9:245:15 | Call: call to strdupa | test.cpp:245:9:245:15 | call to strdupa | test.cpp:245:9:245:15 | call to strdupa | May return stack-allocated memory from $@. | test.cpp:245:9:245:15 | call to strdupa | call to strdupa |
|
||||
| test.cpp:250:9:250:10 | Convert: (void *)... | test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | (void *)... | May return stack-allocated memory from $@. | test.cpp:249:13:249:20 | call to strndupa | call to strndupa |
|
||||
|
||||
@@ -229,4 +229,23 @@ int* id(int* px) {
|
||||
void f() {
|
||||
int x;
|
||||
int* px = id(&x); // GOOD
|
||||
}
|
||||
|
||||
void *alloca(size_t);
|
||||
|
||||
void* test_alloca() {
|
||||
void* p = alloca(10);
|
||||
return p; // BAD
|
||||
}
|
||||
|
||||
char *strdupa(const char *);
|
||||
char *strndupa(const char *, size_t);
|
||||
|
||||
char* test_strdupa(const char* s) {
|
||||
return strdupa(s); // BAD
|
||||
}
|
||||
|
||||
void* test_strndupa(const char* s, size_t size) {
|
||||
char* s2 = strndupa(s, size);
|
||||
return s2; // BAD
|
||||
}
|
||||
@@ -1,23 +1,12 @@
|
||||
edges
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:73:24:73:27 | data | test.cpp:37:73:37:76 | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | data indirection |
|
||||
subpaths
|
||||
nodes
|
||||
| test.cpp:37:73:37:76 | data | semmle.label | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:43:32:43:35 | data | semmle.label | data |
|
||||
| test.cpp:43:32:43:35 | data | semmle.label | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:73:24:73:27 | data | semmle.label | data |
|
||||
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv | call to getenv |
|
||||
| test.cpp:43:32:43:35 | data indirection | test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:43:32:43:35 | data indirection | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv indirection | an environment variable |
|
||||
|
||||
@@ -1,112 +1,48 @@
|
||||
edges
|
||||
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
|
||||
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||
| test.cpp:42:18:42:23 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||
| test.cpp:42:18:42:34 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||
| test.cpp:43:18:43:23 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||
| test.cpp:43:18:43:34 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
subpaths
|
||||
| test.cpp:24:30:24:36 | command indirection | test.cpp:26:10:26:16 | command indirection |
|
||||
| test.cpp:29:30:29:36 | command indirection | test.cpp:31:10:31:16 | command indirection |
|
||||
| test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:24:30:24:36 | command indirection |
|
||||
| test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:29:30:29:36 | command indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection |
|
||||
| test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection |
|
||||
nodes
|
||||
| test.cpp:24:30:24:36 | command | semmle.label | command |
|
||||
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||
| test.cpp:29:30:29:36 | command | semmle.label | command |
|
||||
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:42:18:42:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:24:30:24:36 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:29:30:29:36 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:42:18:42:34 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:43:18:43:34 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:64:10:64:16 | (reference dereference) indirection | semmle.label | (reference dereference) indirection |
|
||||
| test.cpp:64:10:64:16 | dataref indirection | semmle.label | dataref indirection |
|
||||
| test.cpp:65:10:65:14 | data2 indirection | semmle.label | data2 indirection |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument |
|
||||
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
|
||||
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:113:8:113:12 | call to fgets | semmle.label | call to fgets |
|
||||
| test.cpp:113:8:113:12 | call to fgets | semmle.label | call to fgets |
|
||||
| test.cpp:114:9:114:11 | ptr | semmle.label | ptr |
|
||||
| test.cpp:114:9:114:11 | ptr | semmle.label | ptr |
|
||||
| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:113:8:113:12 | call to fgets indirection | semmle.label | call to fgets indirection |
|
||||
| test.cpp:114:9:114:11 | ptr indirection | semmle.label | ptr indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:23 | call to getenv | call to getenv |
|
||||
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:23 | call to getenv | call to getenv |
|
||||
| test.cpp:62:10:62:15 | buffer | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:63:10:63:13 | data | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:64:10:64:16 | dataref | test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:65:10:65:14 | data2 | test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | buffer | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer | test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | buffer | buffer |
|
||||
| test.cpp:107:15:107:20 | buffer | test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | buffer | buffer |
|
||||
| test.cpp:114:9:114:11 | ptr | test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets | call to fgets |
|
||||
| test.cpp:26:10:26:16 | command indirection | test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:26:10:26:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:34 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:31:10:31:16 | command indirection | test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:31:10:31:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:34 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:62:10:62:15 | buffer indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:63:10:63:13 | data indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:64:10:64:16 | (reference dereference) indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:64:10:64:16 | dataref indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:65:10:65:14 | data2 indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:78:10:78:15 | buffer indirection | test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:99:15:99:20 | buffer indirection | test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | recv output argument | buffer read by recv |
|
||||
| test.cpp:107:15:107:20 | buffer indirection | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | recv output argument | buffer read by recv |
|
||||
| test.cpp:114:9:114:11 | ptr indirection | test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets indirection | string read by fgets |
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
edges
|
||||
subpaths
|
||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:10:20:10:23 | argv indirection |
|
||||
| main.cpp:10:20:10:23 | argv indirection | tests.cpp:631:32:631:35 | argv indirection |
|
||||
| tests.cpp:613:19:613:24 | source indirection | tests.cpp:615:17:615:22 | source indirection |
|
||||
| tests.cpp:622:19:622:24 | source indirection | tests.cpp:625:2:625:16 | ... = ... indirection |
|
||||
| tests.cpp:625:2:625:16 | ... = ... indirection | tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] |
|
||||
| tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] | tests.cpp:628:14:628:14 | s indirection [home indirection] |
|
||||
| tests.cpp:628:14:628:14 | s indirection [home indirection] | tests.cpp:628:14:628:19 | home indirection |
|
||||
| tests.cpp:628:14:628:14 | s indirection [home indirection] | tests.cpp:628:16:628:19 | home indirection |
|
||||
| tests.cpp:628:16:628:19 | home indirection | tests.cpp:628:14:628:19 | home indirection |
|
||||
| tests.cpp:631:32:631:35 | argv indirection | tests.cpp:656:9:656:15 | access to array indirection |
|
||||
| tests.cpp:631:32:631:35 | argv indirection | tests.cpp:657:9:657:15 | access to array indirection |
|
||||
| tests.cpp:656:9:656:15 | access to array indirection | tests.cpp:613:19:613:24 | source indirection |
|
||||
| tests.cpp:657:9:657:15 | access to array indirection | tests.cpp:622:19:622:24 | source indirection |
|
||||
nodes
|
||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:10:20:10:23 | argv indirection | semmle.label | argv indirection |
|
||||
| tests.cpp:613:19:613:24 | source indirection | semmle.label | source indirection |
|
||||
| tests.cpp:615:17:615:22 | source indirection | semmle.label | source indirection |
|
||||
| tests.cpp:622:19:622:24 | source indirection | semmle.label | source indirection |
|
||||
| tests.cpp:625:2:625:16 | ... = ... indirection | semmle.label | ... = ... indirection |
|
||||
| tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] | semmle.label | s indirection [post update] [home indirection] |
|
||||
| tests.cpp:628:14:628:14 | s indirection [home indirection] | semmle.label | s indirection [home indirection] |
|
||||
| tests.cpp:628:14:628:19 | home indirection | semmle.label | home indirection |
|
||||
| tests.cpp:628:16:628:19 | home indirection | semmle.label | home indirection |
|
||||
| tests.cpp:631:32:631:35 | argv indirection | semmle.label | argv indirection |
|
||||
| tests.cpp:656:9:656:15 | access to array indirection | semmle.label | access to array indirection |
|
||||
| tests.cpp:657:9:657:15 | access to array indirection | semmle.label | access to array indirection |
|
||||
subpaths
|
||||
#select
|
||||
| tests.cpp:615:2:615:7 | call to strcpy | main.cpp:6:27:6:30 | argv indirection | tests.cpp:615:17:615:22 | source indirection | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | argv indirection | a command-line argument |
|
||||
| tests.cpp:628:2:628:7 | call to strcpy | main.cpp:6:27:6:30 | argv indirection | tests.cpp:628:14:628:19 | home indirection | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -407,7 +407,7 @@ void test15()
|
||||
{
|
||||
if (ptr[5] == ' ') // GOOD
|
||||
{
|
||||
// ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,6 +608,26 @@ int test23() {
|
||||
return sizeof(buffer) / sizeof(buffer[101]); // GOOD
|
||||
}
|
||||
|
||||
char* strcpy(char *, const char *);
|
||||
|
||||
void test24(char* source) {
|
||||
char buffer[100];
|
||||
strcpy(buffer, source); // BAD
|
||||
}
|
||||
|
||||
struct my_struct {
|
||||
char* home;
|
||||
};
|
||||
|
||||
void test25(char* source) {
|
||||
my_struct s;
|
||||
|
||||
s.home = source;
|
||||
|
||||
char buf[100];
|
||||
strcpy(buf, s.home); // BAD
|
||||
}
|
||||
|
||||
int tests_main(int argc, char *argv[])
|
||||
{
|
||||
long long arr17[19];
|
||||
@@ -633,6 +653,8 @@ int tests_main(int argc, char *argv[])
|
||||
test21(argc == 0);
|
||||
test22(argc == 0, argv[0]);
|
||||
test23();
|
||||
test24(argv[0]);
|
||||
test25(argv[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
edges
|
||||
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
|
||||
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
|
||||
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
|
||||
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
|
||||
subpaths
|
||||
nodes
|
||||
| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... |
|
||||
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
|
||||
| examples.cpp:66:11:66:14 | data | semmle.label | data |
|
||||
| examples.cpp:66:11:66:14 | data | semmle.label | data |
|
||||
subpaths
|
||||
#select
|
||||
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value |
|
||||
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |
|
||||
|
||||
@@ -1,86 +1,59 @@
|
||||
edges
|
||||
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
|
||||
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:13:27:13 | v |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v |
|
||||
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
|
||||
| test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
|
||||
| test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:18:6:18:18 | call to getTaintedInt |
|
||||
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
|
||||
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | getTaintedInt indirection |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
subpaths
|
||||
| test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
|
||||
| test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
|
||||
nodes
|
||||
| test2.cpp:12:21:12:21 | v | semmle.label | v |
|
||||
| test2.cpp:14:11:14:11 | v | semmle.label | v |
|
||||
| test2.cpp:14:11:14:11 | v | semmle.label | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
|
||||
| test2.cpp:27:13:27:13 | v | semmle.label | v |
|
||||
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
|
||||
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test2.cpp:39:9:39:11 | num | semmle.label | num |
|
||||
| test2.cpp:39:9:39:11 | num | semmle.label | num |
|
||||
| test2.cpp:40:3:40:5 | num | semmle.label | num |
|
||||
| test2.cpp:40:3:40:5 | num | semmle.label | num |
|
||||
| test3.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | semmle.label | getTaintedInt indirection |
|
||||
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
|
||||
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:19:6:19:6 | y | semmle.label | y |
|
||||
| test5.cpp:19:6:19:6 | y | semmle.label | y |
|
||||
| test.c:11:29:11:32 | argv | semmle.label | argv |
|
||||
| test.c:11:29:11:32 | argv | semmle.label | argv |
|
||||
| test.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
|
||||
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
|
||||
| test.c:41:17:41:20 | argv | semmle.label | argv |
|
||||
| test.c:41:17:41:20 | argv | semmle.label | argv |
|
||||
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
|
||||
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
|
||||
| test.c:51:17:51:20 | argv | semmle.label | argv |
|
||||
| test.c:51:17:51:20 | argv | semmle.label | argv |
|
||||
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
|
||||
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
|
||||
subpaths
|
||||
#select
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
|
||||
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | buf | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:11:29:11:32 | argv | User-provided value |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:11:29:11:32 | argv | User-provided value |
|
||||
| test.c:44:7:44:10 | len2 | test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:41:17:41:20 | argv | User-provided value |
|
||||
| test.c:54:7:54:10 | len3 | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:51:17:51:20 | argv | User-provided value |
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
|
||||
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -159,9 +159,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
|
||||
bool IBuildActions.IsMacOs() => IsMacOs;
|
||||
|
||||
public bool IsArm { get; set; }
|
||||
public bool IsRunningOnAppleSilicon { get; set; }
|
||||
|
||||
bool IBuildActions.IsArm() => IsArm;
|
||||
bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
|
||||
|
||||
public string PathCombine(params string[] parts)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Xml;
|
||||
using Semmle.Util;
|
||||
@@ -119,10 +120,10 @@ namespace Semmle.Autobuild.Shared
|
||||
bool IsMacOs();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether we are running on arm.
|
||||
/// Gets a value indicating whether we are running on Apple Silicon.
|
||||
/// </summary>
|
||||
/// <returns>True if we are running on arm.</returns>
|
||||
bool IsArm();
|
||||
/// <returns>True if we are running on Apple Silicon.</returns>
|
||||
bool IsRunningOnAppleSilicon();
|
||||
|
||||
/// <summary>
|
||||
/// Combine path segments, Path.Combine().
|
||||
@@ -240,9 +241,25 @@ namespace Semmle.Autobuild.Shared
|
||||
|
||||
bool IBuildActions.IsMacOs() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
|
||||
bool IBuildActions.IsArm() =>
|
||||
RuntimeInformation.ProcessArchitecture == Architecture.Arm64 ||
|
||||
RuntimeInformation.ProcessArchitecture == Architecture.Arm;
|
||||
bool IBuildActions.IsRunningOnAppleSilicon()
|
||||
{
|
||||
var thisBuildActions = (IBuildActions)this;
|
||||
|
||||
if (!thisBuildActions.IsMacOs())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
thisBuildActions.RunProcess("sysctl", "machdep.cpu.brand_string", workingDirectory: null, env: null, out var stdOut);
|
||||
return stdOut?.Any(s => s?.ToLowerInvariant().Contains("apple") == true) ?? false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string IBuildActions.PathCombine(params string[] parts) => Path.Combine(parts);
|
||||
|
||||
|
||||
@@ -15,14 +15,12 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <returns></returns>
|
||||
public static CommandBuilder MsBuildCommand(this CommandBuilder cmdBuilder, IAutobuilder<AutobuildOptionsShared> builder)
|
||||
{
|
||||
var isArmMac = builder.Actions.IsMacOs() && builder.Actions.IsArm();
|
||||
|
||||
// mono doesn't ship with `msbuild` on Arm-based Macs, but we can fall back to
|
||||
// msbuild that ships with `dotnet` which can be invoked with `dotnet msbuild`
|
||||
// perhaps we should do this on all platforms?
|
||||
return isArmMac ?
|
||||
cmdBuilder.RunCommand("dotnet").Argument("msbuild") :
|
||||
cmdBuilder.RunCommand("msbuild");
|
||||
return builder.Actions.IsRunningOnAppleSilicon()
|
||||
? cmdBuilder.RunCommand("dotnet").Argument("msbuild")
|
||||
: cmdBuilder.RunCommand("msbuild");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +82,12 @@ namespace Semmle.Autobuild.Shared
|
||||
Argument("/t:restore").
|
||||
QuoteArgument(projectOrSolution.FullPath);
|
||||
|
||||
if (nugetDownloaded)
|
||||
if (builder.Actions.IsRunningOnAppleSilicon())
|
||||
{
|
||||
// On Apple Silicon, only try package restore with `dotnet msbuild /t:restore`
|
||||
ret &= BuildScript.Try(msbuildRestoreCommand.Script);
|
||||
}
|
||||
else if (nugetDownloaded)
|
||||
{
|
||||
ret &= BuildScript.Try(nugetRestore | msbuildRestoreCommand.Script);
|
||||
}
|
||||
|
||||
@@ -89,8 +89,10 @@ namespace Semmle.Extraction.CSharp.Populators
|
||||
SyntaxKind.ModuleKeyword => Entities.AttributeKind.Module,
|
||||
_ => throw new InternalError(node, "Unhandled global target")
|
||||
};
|
||||
foreach (var attribute in node.Attributes)
|
||||
var attributes = node.Attributes;
|
||||
for (var i = 0; i < attributes.Count; i++)
|
||||
{
|
||||
var attribute = attributes[i];
|
||||
if (attributeLookup.Value(attribute) is AttributeData attributeData)
|
||||
{
|
||||
var ae = Entities.Attribute.Create(Cx, attributeData, outputAssembly, kind);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.2
|
||||
lastReleaseVersion: 1.7.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.3-dev
|
||||
version: 1.7.3
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.2
|
||||
lastReleaseVersion: 1.7.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.3-dev
|
||||
version: 1.7.3
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -2,10 +2,10 @@ import os
|
||||
from create_database_utils import *
|
||||
from diagnostics_test_utils import *
|
||||
|
||||
run_codeql_database_create(['dotnet pack'], db=None, lang="csharp")
|
||||
run_codeql_database_create(['dotnet pack -o nugetpackage'], db=None, lang="csharp")
|
||||
|
||||
## Check that the NuGet package is created.
|
||||
if not os.path.isfile("bin/Debug/dotnet_pack.1.0.0.nupkg"):
|
||||
if not os.path.isfile("nugetpackage/dotnet_pack.1.0.0.nupkg"):
|
||||
raise Exception("The NuGet package was not created.")
|
||||
|
||||
check_diagnostics()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<OutputType>Exe</OutputType>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Skipping the test on the ARM runners, as we're running into trouble with Mono and nuget.
|
||||
@@ -1,3 +1,49 @@
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The predicate `UnboundGeneric::getName` now prints the number of type parameters as a `` `N`` suffix, instead of a `<,...,>` suffix. For example, the unbound generic type
|
||||
`System.Collections.Generic.IList<T>` is printed as ``IList`1`` instead of `IList<>`.
|
||||
* The predicates `hasQualifiedName`, `getQualifiedName`, and `getQualifiedNameWithTypes` have been deprecated, and are instead replaced by `hasFullyQualifiedName`, `getFullyQualifiedName`, and `getFullyQualifiedNameWithTypes`, respectively. The new predicates use the same format for unbound generic types as mentioned above.
|
||||
* These changes also affect models-as-data rows that refer to a field or a property belonging to a generic type. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
|
||||
```
|
||||
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
|
||||
## 0.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
|
||||
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The predicate `UnboundGeneric::getName` now prints the number of type parameters as a `` `N`` suffix, instead of a `<,...,>` suffix. For example, the unbound generic type
|
||||
`System.Collections.Generic.IList<T>` is printed as ``IList`1`` instead of `IList<>`.
|
||||
@@ -23,3 +23,23 @@ extensions:
|
||||
data:
|
||||
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
|
||||
```
|
||||
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.3
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.3
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| standalone.cs:3:12:3:29 | [assembly: Attribute1(...)] |
|
||||
| standalone.cs:9:2:9:11 | [Attribute1(...)] |
|
||||
@@ -0,0 +1,5 @@
|
||||
import csharp
|
||||
|
||||
from Attribute a
|
||||
where a.getType().getName() = "Attribute1Attribute"
|
||||
select a
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --standalone
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
[assembly: global::Attribute1]
|
||||
|
||||
class Attribute1Attribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[Attribute1]
|
||||
class A
|
||||
{
|
||||
}
|
||||
@@ -42,14 +42,47 @@ Downloading a database from GitHub
|
||||
|
||||
.. include:: ../reusables/download-github-database.rst
|
||||
|
||||
.. _filtering-databases-and-queries-by-language:
|
||||
|
||||
Filtering databases and queries by language
|
||||
-------------------------------------------
|
||||
|
||||
Optionally, to see databases containing a specific language and queries written for that language, you can apply a language filter using the language selector.
|
||||
|
||||
#. To see available language filters, in the sidebar, click the **Language** title bar.
|
||||
#. Hover over the language filter you would like to apply, then click **Select**.
|
||||
|
||||
.. image:: ../images/codeql-for-visual-studio-code/choose-language-filter.png
|
||||
:width: 350
|
||||
:alt: Screenshot of the language selector. The "Select" button for a language filter is outlined in dark orange.
|
||||
|
||||
Creating a custom query
|
||||
------------------------
|
||||
|
||||
You can generate a query template for a specific language from the queries panel, then write your own code to quickly create a custom query.
|
||||
|
||||
#. Optionally, to create a custom query in an existing directory, in the sidebar, click the **Queries** title bar to expand the queries panel, then select the desired directory.
|
||||
#. In the sidebar, hover over the **Queries** title bar, then click the **Create query** icon.
|
||||
|
||||
.. image:: ../images/codeql-for-visual-studio-code/create-query-icon.png
|
||||
:width: 350
|
||||
:alt: Screenshot of the queries panel. The "Create query" icon is outlined in dark orange.
|
||||
|
||||
#. In the Command Palette, select the target language for your query. If you've chosen not to create your custom query in an existing directory, selecting a language will autogenerate a directory labeled ``codeql-custom-queries-<language>``, where ``<language>`` is the name of the selected language. A query template labeled ``example.ql`` will then be added to the existing or autogenerated directory.
|
||||
#. In the template, write your custom query, then save the file. Once your query is finished, you can run it from the queries panel.
|
||||
|
||||
Running a query
|
||||
------------------------
|
||||
|
||||
The `CodeQL repository <https://github.com/github/codeql>`__ on GitHub contains lots of example queries.
|
||||
If you have that folder (or a different CodeQL pack) available in your workspace, you can access existing queries under ``<language>/ql/src/<category>``, for example ``java/ql/src/Likely Bugs``.
|
||||
You can access any existing queries in your workspace through the queries panel.
|
||||
|
||||
#. Open a query (``.ql``) file. It is displayed in the editor, with IntelliSense features such as syntax highlighting and autocomplete suggestions.
|
||||
#. Right-click in the query window and select **CodeQL: Run Query on Selected Database**. (Alternatively, run the command from the Command Palette.)
|
||||
#. In the sidebar, to expand the queries panel, click the **Queries** title bar.
|
||||
#. To run a query against the selected database, hover over the desired query, then click the **Run local query** icon.
|
||||
|
||||
.. image:: ../images/codeql-for-visual-studio-code/run-local-query-icon.png
|
||||
:width: 350
|
||||
:alt: Screenshot of the mouse pointer hovering over a query in the queries panel. The "Run local query" icon is outlined in dark orange.
|
||||
|
||||
The CodeQL extension runs the query on the current database and reports progress in the bottom right corner of the application.
|
||||
When the results are ready, they're displayed in the Results view.
|
||||
@@ -61,6 +94,23 @@ For more information, see ":doc:`Troubleshooting CodeQL for Visual Studio Code <
|
||||
Running multiple queries
|
||||
--------------------------
|
||||
|
||||
You can quickly run multiple queries against the database you've selected using the queries panel or a single command.
|
||||
|
||||
Running all queries in a directory
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can easily run every query in a directory using the queries panel.
|
||||
|
||||
#. In the sidebar, to expand the queries panel, click the **Queries** title bar.
|
||||
#. Hover over the desired directory of queries, then click the **Run local queries** icon.
|
||||
|
||||
.. image:: ../images/codeql-for-visual-studio-code/run-local-queries-icon.png
|
||||
:width: 350
|
||||
:alt: Screenshot of the mouse pointer hovering over a directory of queries in the queries panel. The "Run local queries" icon is outlined in dark orange.
|
||||
|
||||
Running a selection of queries
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can run multiple queries with a single command.
|
||||
|
||||
#. Go to the File Explorer.
|
||||
@@ -122,6 +172,7 @@ To see the queries that you have run in the current session, open the Query Hist
|
||||
|
||||
The Query History contains information including the date and time when the query was run, the name of the query, the database on which it was run, and how long it took to run the query.
|
||||
To customize the information that is displayed, right-click an entry and select **Rename**.
|
||||
You can also filter the Query History view by language using the language selector. For more information, see ":ref:`Filtering databases and queries by language <filtering-databases-and-queries-by-language>`."
|
||||
|
||||
Click an entry to display the corresponding results in the Query Results view, and double-click
|
||||
to display the query itself in the editor (or right-click and select **View Query**).
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -49,7 +49,7 @@ The following properties are supported by all query files:
|
||||
| | | ``warning`` | |
|
||||
| | | ``recommendation`` | |
|
||||
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``@security-severity``| ``<score>`` | Defines the level of severity, between 0.0 and 10.0, for queries with ``@tags security``. For more information about calculating ``@security-severity``, see the `GitHub changelog <https://github.blog/changelog/2021-07-19-codeql-code-scanning-new-severity-levels-for-security-alerts/>`__. |
|
||||
| ``@security-severity``| ``<score>`` | Defines the level of severity, between 0.0 and 10.0, for queries with ``@tags security``. For more information about calculating ``@security-severity``, see the `GitHub changelog <https://gh.io/2021-07-19-codeql-security-severity>`__. |
|
||||
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Example
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.0.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
go/ql/consistency-queries/change-notes/released/0.0.2.md
Normal file
3
go/ql/consistency-queries/change-notes/released/0.0.2.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.0.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.1
|
||||
lastReleaseVersion: 0.0.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql-go-consistency-queries
|
||||
version: 0.0.2-dev
|
||||
version: 0.0.2
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.7.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added the [gin cors](https://github.com/gin-contrib/cors) library to the CorsMisconfiguration.ql query
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A bug has been fixed that meant that value flow through an array was not tracked correctly in some circumstances. Taint flow was tracked correctly.
|
||||
|
||||
## 0.7.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
9
go/ql/lib/change-notes/released/0.7.3.md
Normal file
9
go/ql/lib/change-notes/released/0.7.3.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 0.7.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added the [gin cors](https://github.com/gin-contrib/cors) library to the CorsMisconfiguration.ql query
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* A bug has been fixed that meant that value flow through an array was not tracked correctly in some circumstances. Taint flow was tracked correctly.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.7.2
|
||||
lastReleaseVersion: 0.7.3
|
||||
|
||||
@@ -41,6 +41,7 @@ import semmle.go.frameworks.Email
|
||||
import semmle.go.frameworks.Encoding
|
||||
import semmle.go.frameworks.Fiber
|
||||
import semmle.go.frameworks.Gin
|
||||
import semmle.go.frameworks.GinCors
|
||||
import semmle.go.frameworks.Glog
|
||||
import semmle.go.frameworks.GoKit
|
||||
import semmle.go.frameworks.GoMicro
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-all
|
||||
version: 0.7.3-dev
|
||||
version: 0.7.3
|
||||
groups: go
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
|
||||
@@ -724,16 +724,19 @@ class GenericTypeInstantiationExpr extends Expr {
|
||||
* ```go
|
||||
* a[1:3]
|
||||
* a[1:3:5]
|
||||
* a[1:]
|
||||
* a[:3]
|
||||
* a[:]
|
||||
* ```
|
||||
*/
|
||||
class SliceExpr extends @sliceexpr, Expr {
|
||||
/** Gets the base of this slice expression. */
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the lower bound of this slice expression. */
|
||||
/** Gets the lower bound of this slice expression, if any. */
|
||||
Expr getLow() { result = this.getChildExpr(1) }
|
||||
|
||||
/** Gets the upper bound of this slice expression. */
|
||||
/** Gets the upper bound of this slice expression, if any. */
|
||||
Expr getHigh() { result = this.getChildExpr(2) }
|
||||
|
||||
/** Gets the maximum of this slice expression, if any. */
|
||||
|
||||
@@ -21,7 +21,7 @@ predicate containerStoreStep(Node node1, Node node2, Content c) {
|
||||
node2.getType() instanceof SliceType
|
||||
) and
|
||||
(
|
||||
exists(Write w | w.writesElement(node2, _, node1))
|
||||
exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), _, node1))
|
||||
or
|
||||
node1 = node2.(ImplicitVarargsSlice).getCallNode().getAnImplicitVarargsArgument()
|
||||
)
|
||||
|
||||
139
go/ql/lib/semmle/go/frameworks/GinCors.qll
Normal file
139
go/ql/lib/semmle/go/frameworks/GinCors.qll
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Provides classes for modeling the `github.com/gin-contrib/cors` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/**
|
||||
* Provides classes for modeling the `github.com/gin-contrib/cors` package.
|
||||
*/
|
||||
module GinCors {
|
||||
/** Gets the package name `github.com/gin-gonic/gin`. */
|
||||
string packagePath() { result = package("github.com/gin-contrib/cors", "") }
|
||||
|
||||
/**
|
||||
* A new function create a new gin Handler that passed to gin as middleware
|
||||
*/
|
||||
class New extends Function {
|
||||
New() { exists(Function f | f.hasQualifiedName(packagePath(), "New") | this = f) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A write to the value of Access-Control-Allow-Credentials header
|
||||
*/
|
||||
class AllowCredentialsWrite extends DataFlow::ExprNode {
|
||||
DataFlow::Node base;
|
||||
|
||||
AllowCredentialsWrite() {
|
||||
exists(Field f, Write w |
|
||||
f.hasQualifiedName(packagePath(), "Config", "AllowCredentials") and
|
||||
w.writesField(base, f, this) and
|
||||
this.getType() instanceof BoolType
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config struct holding header values
|
||||
*/
|
||||
DataFlow::Node getBase() { result = base }
|
||||
|
||||
/**
|
||||
* Get config variable holding header values
|
||||
*/
|
||||
GinConfig getConfig() {
|
||||
exists(GinConfig gc |
|
||||
(
|
||||
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
|
||||
base.asInstruction() or
|
||||
gc.getV().getAUse() = base
|
||||
) and
|
||||
result = gc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A write to the value of Access-Control-Allow-Origins header
|
||||
*/
|
||||
class AllowOriginsWrite extends DataFlow::ExprNode {
|
||||
DataFlow::Node base;
|
||||
|
||||
AllowOriginsWrite() {
|
||||
exists(Field f, Write w |
|
||||
f.hasQualifiedName(packagePath(), "Config", "AllowOrigins") and
|
||||
w.writesField(base, f, this) and
|
||||
this.asExpr() instanceof SliceLit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config struct holding header values
|
||||
*/
|
||||
DataFlow::Node getBase() { result = base }
|
||||
|
||||
/**
|
||||
* Get config variable holding header values
|
||||
*/
|
||||
GinConfig getConfig() {
|
||||
exists(GinConfig gc |
|
||||
(
|
||||
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
|
||||
base.asInstruction() or
|
||||
gc.getV().getAUse() = base
|
||||
) and
|
||||
result = gc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A write to the value of Access-Control-Allow-Origins of value "*", overriding AllowOrigins
|
||||
*/
|
||||
class AllowAllOriginsWrite extends DataFlow::ExprNode {
|
||||
DataFlow::Node base;
|
||||
|
||||
AllowAllOriginsWrite() {
|
||||
exists(Field f, Write w |
|
||||
f.hasQualifiedName(packagePath(), "Config", "AllowAllOrigins") and
|
||||
w.writesField(base, f, this) and
|
||||
this.getType() instanceof BoolType
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config struct holding header values
|
||||
*/
|
||||
DataFlow::Node getBase() { result = base }
|
||||
|
||||
/**
|
||||
* Get config variable holding header values
|
||||
*/
|
||||
GinConfig getConfig() {
|
||||
exists(GinConfig gc |
|
||||
(
|
||||
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
|
||||
base.asInstruction() or
|
||||
gc.getV().getAUse() = base
|
||||
) and
|
||||
result = gc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A variable of type Config that holds the headers to be set.
|
||||
*/
|
||||
class GinConfig extends Variable {
|
||||
SsaWithFields v;
|
||||
|
||||
GinConfig() {
|
||||
this = v.getBaseVariable().getSourceVariable() and
|
||||
exists(Type t | t.hasQualifiedName(packagePath(), "Config") | v.getType() = t)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variable declaration of GinConfig
|
||||
*/
|
||||
SsaWithFields getV() { result = v }
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.7.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.7.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
3
go/ql/src/change-notes/released/0.7.3.md
Normal file
3
go/ql/src/change-notes/released/0.7.3.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.7.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.7.2
|
||||
lastReleaseVersion: 0.7.3
|
||||
|
||||
@@ -69,22 +69,53 @@ module UntrustedToAllowOriginHeaderConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { isSinkHW(sink, _) }
|
||||
}
|
||||
|
||||
module UntrustedToAllowOriginConfigConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
|
||||
|
||||
additional predicate isSinkWrite(DataFlow::Node sink, GinCors::AllowOriginsWrite w) { sink = w }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSinkWrite(sink, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks taint flowfor reasoning about when an `UntrustedFlowSource` flows to
|
||||
* a `HeaderWrite` that writes an `Access-Control-Allow-Origin` header's value.
|
||||
*/
|
||||
module UntrustedToAllowOriginHeaderFlow = TaintTracking::Global<UntrustedToAllowOriginHeaderConfig>;
|
||||
|
||||
/**
|
||||
* Tracks taint flowfor reasoning about when an `UntrustedFlowSource` flows to
|
||||
* a `AllowOriginsWrite` that writes an `Access-Control-Allow-Origin` header's value.
|
||||
*/
|
||||
module UntrustedToAllowOriginConfigFlow = TaintTracking::Global<UntrustedToAllowOriginConfigConfig>;
|
||||
|
||||
/**
|
||||
* Holds if the provided `allowOriginHW` HeaderWrite's parent ResponseWriter
|
||||
* also has another HeaderWrite that sets a `Access-Control-Allow-Credentials`
|
||||
* header to `true`.
|
||||
*/
|
||||
predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) {
|
||||
predicate allowCredentialsIsSetToTrue(DataFlow::ExprNode allowOriginHW) {
|
||||
exists(AllowCredentialsHeaderWrite allowCredentialsHW |
|
||||
allowCredentialsHW.getHeaderValue().toLowerCase() = "true"
|
||||
|
|
||||
allowOriginHW.getResponseWriter() = allowCredentialsHW.getResponseWriter()
|
||||
allowOriginHW.(AllowOriginHeaderWrite).getResponseWriter() =
|
||||
allowCredentialsHW.getResponseWriter()
|
||||
)
|
||||
or
|
||||
exists(GinCors::AllowCredentialsWrite allowCredentialsGin |
|
||||
allowCredentialsGin.getExpr().getBoolValue() = true
|
||||
|
|
||||
allowCredentialsGin.getConfig() = allowOriginHW.(GinCors::AllowOriginsWrite).getConfig() and
|
||||
not exists(GinCors::AllowAllOriginsWrite allowAllOrigins |
|
||||
allowAllOrigins.getExpr().getBoolValue() = true and
|
||||
allowCredentialsGin.getConfig() = allowAllOrigins.getConfig()
|
||||
)
|
||||
or
|
||||
allowCredentialsGin.getBase() = allowOriginHW.(GinCors::AllowOriginsWrite).getBase() and
|
||||
not exists(GinCors::AllowAllOriginsWrite allowAllOrigins |
|
||||
allowAllOrigins.getExpr().getBoolValue() = true and
|
||||
allowCredentialsGin.getBase() = allowAllOrigins.getBase()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -93,10 +124,13 @@ predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) {
|
||||
* UntrustedFlowSource.
|
||||
* The `message` parameter is populated with the warning message to be returned by the query.
|
||||
*/
|
||||
predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW, string message) {
|
||||
predicate flowsFromUntrustedToAllowOrigin(DataFlow::ExprNode allowOriginHW, string message) {
|
||||
exists(DataFlow::Node sink |
|
||||
UntrustedToAllowOriginHeaderFlow::flowTo(sink) and
|
||||
UntrustedToAllowOriginHeaderConfig::isSinkHW(sink, allowOriginHW)
|
||||
or
|
||||
UntrustedToAllowOriginConfigFlow::flowTo(sink) and
|
||||
UntrustedToAllowOriginConfigConfig::isSinkWrite(sink, allowOriginHW)
|
||||
|
|
||||
message =
|
||||
headerAllowOrigin() + " header is set to a user-defined value, and " +
|
||||
@@ -108,11 +142,23 @@ predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW,
|
||||
* Holds if the provided `allowOriginHW` HeaderWrite is for a `Access-Control-Allow-Origin`
|
||||
* header and the value is set to `null`.
|
||||
*/
|
||||
predicate allowOriginIsNull(AllowOriginHeaderWrite allowOriginHW, string message) {
|
||||
allowOriginHW.getHeaderValue().toLowerCase() = "null" and
|
||||
predicate allowOriginIsNull(DataFlow::ExprNode allowOriginHW, string message) {
|
||||
allowOriginHW.(AllowOriginHeaderWrite).getHeaderValue().toLowerCase() = "null" and
|
||||
message =
|
||||
headerAllowOrigin() + " header is set to `" + allowOriginHW.getHeaderValue() + "`, and " +
|
||||
headerAllowCredentials() + " is set to `true`"
|
||||
headerAllowOrigin() + " header is set to `" +
|
||||
allowOriginHW.(AllowOriginHeaderWrite).getHeaderValue() + "`, and " + headerAllowCredentials()
|
||||
+ " is set to `true`"
|
||||
or
|
||||
allowOriginHW
|
||||
.(GinCors::AllowOriginsWrite)
|
||||
.asExpr()
|
||||
.(SliceLit)
|
||||
.getAnElement()
|
||||
.getStringValue()
|
||||
.toLowerCase() = "null" and
|
||||
message =
|
||||
headerAllowOrigin() + " header is set to `" + "null" + "`, and " + headerAllowCredentials() +
|
||||
" is set to `true`"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +216,7 @@ module FromUntrustedFlow = TaintTracking::Global<FromUntrustedConfig>;
|
||||
/**
|
||||
* Holds if the provided `allowOriginHW` is also destination of a `UntrustedFlowSource`.
|
||||
*/
|
||||
predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW) {
|
||||
predicate flowsToGuardedByCheckOnUntrusted(DataFlow::ExprNode allowOriginHW) {
|
||||
exists(DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn |
|
||||
FromUntrustedFlow::flowTo(sink) and FromUntrustedConfig::isSinkCgn(sink, cgn)
|
||||
|
|
||||
@@ -178,7 +224,7 @@ predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW)
|
||||
)
|
||||
}
|
||||
|
||||
from AllowOriginHeaderWrite allowOriginHW, string message
|
||||
from DataFlow::ExprNode allowOriginHW, string message
|
||||
where
|
||||
allowCredentialsIsSetToTrue(allowOriginHW) and
|
||||
(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 0.7.3-dev
|
||||
version: 0.7.3
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
106
go/ql/test/experimental/CWE-942/CorsGin.go
Normal file
106
go/ql/test/experimental/CWE-942/CorsGin.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
/*
|
||||
** Function is vulnerable due to AllowAllOrigins = true aka Access-Control-Allow-Origin: null
|
||||
*/
|
||||
func vunlnerable() {
|
||||
router := gin.Default()
|
||||
// CORS for https://foo.com and null
|
||||
// - PUT and PATCH methods
|
||||
// - Origin header
|
||||
// - Credentials share
|
||||
// - Preflight requests cached for 12 hours
|
||||
config_vulnerable := cors.Config{
|
||||
AllowMethods: []string{"PUT", "PATCH"},
|
||||
AllowHeaders: []string{"Origin"},
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * time.Hour,
|
||||
}
|
||||
config_vulnerable.AllowOrigins = []string{"null", "https://foo.com"}
|
||||
router.Use(cors.New(config_vulnerable))
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "hello world")
|
||||
})
|
||||
router.Run()
|
||||
}
|
||||
|
||||
/*
|
||||
** Function is safe due to hardcoded origin and AllowCredentials: true
|
||||
*/
|
||||
func safe() {
|
||||
router := gin.Default()
|
||||
// CORS for https://foo.com origin, allowing:
|
||||
// - PUT and PATCH methods
|
||||
// - Origin header
|
||||
// - Credentials share
|
||||
// - Preflight requests cached for 12 hours
|
||||
config_safe := cors.Config{
|
||||
AllowMethods: []string{"PUT", "PATCH"},
|
||||
AllowHeaders: []string{"Origin"},
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * time.Hour,
|
||||
}
|
||||
config_safe.AllowOrigins = []string{"https://foo.com"}
|
||||
router.Use(cors.New(config_safe))
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "hello world")
|
||||
})
|
||||
router.Run()
|
||||
}
|
||||
|
||||
/*
|
||||
** Function is safe due to AllowAllOrigins = true aka Access-Control-Allow-Origin: *
|
||||
*/
|
||||
func AllowAllTrue() {
|
||||
router := gin.Default()
|
||||
// CORS for "*" origin, allowing:
|
||||
// - PUT and PATCH methods
|
||||
// - Origin header
|
||||
// - Credentials share
|
||||
// - Preflight requests cached for 12 hours
|
||||
config_allowall := cors.Config{
|
||||
AllowMethods: []string{"PUT", "PATCH"},
|
||||
AllowHeaders: []string{"Origin"},
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * time.Hour,
|
||||
}
|
||||
config_allowall.AllowOrigins = []string{"null"}
|
||||
config_allowall.AllowAllOrigins = true
|
||||
router.Use(cors.New(config_allowall))
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "hello world")
|
||||
})
|
||||
router.Run()
|
||||
}
|
||||
|
||||
func NoVariableVulnerable() {
|
||||
router := gin.Default()
|
||||
// CORS for https://foo.com origin, allowing:
|
||||
// - PUT and PATCH methods
|
||||
// - Origin header
|
||||
// - Credentials share
|
||||
// - Preflight requests cached for 12 hours
|
||||
router.Use(cors.New(cors.Config{
|
||||
AllowMethods: []string{"GET", "POST"},
|
||||
AllowHeaders: []string{"Origin"},
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
AllowOrigins: []string{"null", "https://foo.com"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * time.Hour,
|
||||
}))
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "hello world")
|
||||
})
|
||||
router.Run()
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
| CorsGin.go:28:35:28:69 | slice literal | access-control-allow-origin header is set to `null`, and access-control-allow-credentials is set to `true` |
|
||||
| CorsGin.go:98:21:98:55 | slice literal | access-control-allow-origin header is set to `null`, and access-control-allow-credentials is set to `true` |
|
||||
| CorsMisconfiguration.go:26:4:26:56 | call to Set | access-control-allow-origin header is set to `null`, and access-control-allow-credentials is set to `true` |
|
||||
| CorsMisconfiguration.go:32:4:32:42 | call to Set | access-control-allow-origin header is set to `null`, and access-control-allow-credentials is set to `true` |
|
||||
| CorsMisconfiguration.go:53:4:53:44 | call to Set | access-control-allow-origin header is set to a user-defined value, and access-control-allow-credentials is set to `true` |
|
||||
|
||||
@@ -191,9 +191,9 @@ func main() {
|
||||
// })
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
||||
// OK-ish: the input origin header is validated against a whitelist.
|
||||
if origin := req.Header.Get("Origin"); cors[origin] {
|
||||
if origin := req.Header.Get("Origin"); cors_map[origin] {
|
||||
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
} else if len(origin) > 0 && cors["*"] {
|
||||
} else if len(origin) > 0 && cors_map["*"] {
|
||||
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ func main() {
|
||||
}
|
||||
|
||||
var (
|
||||
cors = map[string]bool{"*": true}
|
||||
cors_map = map[string]bool{"*": true}
|
||||
)
|
||||
|
||||
func GetAllowOrigin() []string {
|
||||
|
||||
35
go/ql/test/experimental/CWE-942/go.mod
Normal file
35
go/ql/test/experimental/CWE-942/go.mod
Normal file
@@ -0,0 +1,35 @@
|
||||
module corsmiconfiguration/test
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/cors v1.4.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
43
go/ql/test/experimental/CWE-942/vendor/github.com/gin-contrib/cors/stub.go
generated
vendored
Normal file
43
go/ql/test/experimental/CWE-942/vendor/github.com/gin-contrib/cors/stub.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gin-contrib/cors, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gin-contrib/cors (exports: Config; functions: New)
|
||||
|
||||
// Package cors is a stub of github.com/gin-contrib/cors, generated by depstubber.
|
||||
package cors
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
AllowAllOrigins bool
|
||||
AllowOrigins []string
|
||||
AllowOriginFunc func(string) bool
|
||||
AllowMethods []string
|
||||
AllowHeaders []string
|
||||
AllowCredentials bool
|
||||
ExposeHeaders []string
|
||||
MaxAge time.Duration
|
||||
AllowWildcard bool
|
||||
AllowBrowserExtensions bool
|
||||
AllowWebSockets bool
|
||||
AllowFiles bool
|
||||
}
|
||||
|
||||
func (_ Config) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Config) AddAllowHeaders(_ ...string) {}
|
||||
|
||||
func (_ *Config) AddAllowMethods(_ ...string) {}
|
||||
|
||||
func (_ *Config) AddExposeHeaders(_ ...string) {}
|
||||
|
||||
func New(_ Config) gin.HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
719
go/ql/test/experimental/CWE-942/vendor/github.com/gin-gonic/gin/stub.go
generated
vendored
Normal file
719
go/ql/test/experimental/CWE-942/vendor/github.com/gin-gonic/gin/stub.go
generated
vendored
Normal file
@@ -0,0 +1,719 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gin-gonic/gin, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gin-gonic/gin (exports: Context,Engine; functions: Default)
|
||||
|
||||
// Package gin is a stub of github.com/gin-gonic/gin, generated by depstubber.
|
||||
package gin
|
||||
|
||||
import (
|
||||
bufio "bufio"
|
||||
template "html/template"
|
||||
io "io"
|
||||
multipart "mime/multipart"
|
||||
net "net"
|
||||
http "net/http"
|
||||
template0 "text/template"
|
||||
time "time"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Request *http.Request
|
||||
Writer ResponseWriter
|
||||
Params Params
|
||||
Keys map[string]interface{}
|
||||
Errors interface{}
|
||||
Accepted []string
|
||||
}
|
||||
|
||||
func (_ *Context) Abort() {}
|
||||
|
||||
func (_ *Context) AbortWithError(_ int, _ error) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) AbortWithStatus(_ int) {}
|
||||
|
||||
func (_ *Context) AbortWithStatusJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) AddParam(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) AsciiJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Bind(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindHeader(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindQuery(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindTOML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindUri(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindXML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindYAML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ClientIP() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Cookie(_ string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ *Context) Copy() *Context {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Data(_ int, _ string, _ []byte) {}
|
||||
|
||||
func (_ *Context) DataFromReader(_ int, _ int64, _ string, _ io.Reader, _ map[string]string) {}
|
||||
|
||||
func (_ *Context) Deadline() (time.Time, bool) {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func (_ *Context) DefaultPostForm(_ string, _ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) DefaultQuery(_ string, _ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Error(_ error) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) File(_ string) {}
|
||||
|
||||
func (_ *Context) FileAttachment(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) FileFromFS(_ string, _ http.FileSystem) {}
|
||||
|
||||
func (_ *Context) FormFile(_ string) (*multipart.FileHeader, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) FullPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Get(_ string) (interface{}, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetBool(_ string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) GetDuration(_ string) time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetFloat64(_ string) float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetHeader(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) GetInt(_ string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetInt64(_ string) int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostForm(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostFormArray(_ string) ([]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostFormMap(_ string) (map[string]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQuery(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQueryArray(_ string) ([]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQueryMap(_ string) (map[string]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetRawData() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetString(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMap(_ string) map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMapString(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMapStringSlice(_ string) map[string][]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringSlice(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetTime(_ string) time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (_ *Context) GetUint(_ string) uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetUint64(_ string) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) HTML(_ int, _ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Handler() HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) HandlerName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) HandlerNames() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Header(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) IndentedJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) IsAborted() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) IsWebsocket() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) JSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) JSONP(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) MultipartForm() (*multipart.Form, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) MustBindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) MustGet(_ string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Negotiate(_ int, _ Negotiate) {}
|
||||
|
||||
func (_ *Context) NegotiateFormat(_ ...string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Next() {}
|
||||
|
||||
func (_ *Context) Param(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) PostForm(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) PostFormArray(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) PostFormMap(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ProtoBuf(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) PureJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Query(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) QueryArray(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) QueryMap(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Redirect(_ int, _ string) {}
|
||||
|
||||
func (_ *Context) RemoteIP() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Render(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SSEvent(_ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SaveUploadedFile(_ *multipart.FileHeader, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) SecureJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Set(_ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SetAccepted(_ ...string) {}
|
||||
|
||||
func (_ *Context) SetCookie(_ string, _ string, _ int, _ string, _ string, _ bool, _ bool) {}
|
||||
|
||||
func (_ *Context) SetSameSite(_ http.SameSite) {}
|
||||
|
||||
func (_ *Context) ShouldBind(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindBodyWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindHeader(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindQuery(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindTOML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindUri(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindXML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindYAML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Status(_ int) {}
|
||||
|
||||
func (_ *Context) Stream(_ func(io.Writer) bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) String(_ int, _ string, _ ...interface{}) {}
|
||||
|
||||
func (_ *Context) TOML(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Value(_ interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) XML(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) YAML(_ int, _ interface{}) {}
|
||||
|
||||
func Default() *Engine {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Engine struct {
|
||||
RouterGroup RouterGroup
|
||||
RedirectTrailingSlash bool
|
||||
RedirectFixedPath bool
|
||||
HandleMethodNotAllowed bool
|
||||
ForwardedByClientIP bool
|
||||
AppEngine bool
|
||||
UseRawPath bool
|
||||
UnescapePathValues bool
|
||||
RemoveExtraSlash bool
|
||||
RemoteIPHeaders []string
|
||||
TrustedPlatform string
|
||||
MaxMultipartMemory int64
|
||||
UseH2C bool
|
||||
ContextWithFallback bool
|
||||
HTMLRender interface{}
|
||||
FuncMap template0.FuncMap
|
||||
}
|
||||
|
||||
func (_ *Engine) Any(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) BasePath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Engine) DELETE(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Delims(_ string, _ string) *Engine {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) GET(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Group(_ string, _ ...HandlerFunc) *RouterGroup {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) HEAD(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Handle(_ string, _ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) HandleContext(_ *Context) {}
|
||||
|
||||
func (_ *Engine) Handler() http.Handler {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) LoadHTMLFiles(_ ...string) {}
|
||||
|
||||
func (_ *Engine) LoadHTMLGlob(_ string) {}
|
||||
|
||||
func (_ *Engine) Match(_ []string, _ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) NoMethod(_ ...HandlerFunc) {}
|
||||
|
||||
func (_ *Engine) NoRoute(_ ...HandlerFunc) {}
|
||||
|
||||
func (_ *Engine) OPTIONS(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) PATCH(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) POST(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) PUT(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Routes() RoutesInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Run(_ ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunFd(_ int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunListener(_ net.Listener) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunTLS(_ string, _ string, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunUnix(_ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) SecureJsonPrefix(_ string) *Engine {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
|
||||
|
||||
func (_ *Engine) SetFuncMap(_ template0.FuncMap) {}
|
||||
|
||||
func (_ *Engine) SetHTMLTemplate(_ *template.Template) {}
|
||||
|
||||
func (_ *Engine) SetTrustedProxies(_ []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Static(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) StaticFS(_ string, _ http.FileSystem) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) StaticFile(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) StaticFileFS(_ string, _ string, _ http.FileSystem) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Use(_ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Err error
|
||||
Type ErrorType
|
||||
Meta interface{}
|
||||
}
|
||||
|
||||
func (_ Error) Error() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Error) IsType(_ ErrorType) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Error) JSON() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) MarshalJSON() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Error) SetMeta(_ interface{}) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) SetType(_ ErrorType) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) Unwrap() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ErrorType uint64
|
||||
|
||||
type HandlerFunc func(*Context)
|
||||
|
||||
type HandlersChain []HandlerFunc
|
||||
|
||||
func (_ HandlersChain) Last() HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
|
||||
type IRoutes interface {
|
||||
Any(_ string, _ ...HandlerFunc) IRoutes
|
||||
DELETE(_ string, _ ...HandlerFunc) IRoutes
|
||||
GET(_ string, _ ...HandlerFunc) IRoutes
|
||||
HEAD(_ string, _ ...HandlerFunc) IRoutes
|
||||
Handle(_ string, _ string, _ ...HandlerFunc) IRoutes
|
||||
Match(_ []string, _ string, _ ...HandlerFunc) IRoutes
|
||||
OPTIONS(_ string, _ ...HandlerFunc) IRoutes
|
||||
PATCH(_ string, _ ...HandlerFunc) IRoutes
|
||||
POST(_ string, _ ...HandlerFunc) IRoutes
|
||||
PUT(_ string, _ ...HandlerFunc) IRoutes
|
||||
Static(_ string, _ string) IRoutes
|
||||
StaticFS(_ string, _ http.FileSystem) IRoutes
|
||||
StaticFile(_ string, _ string) IRoutes
|
||||
StaticFileFS(_ string, _ string, _ http.FileSystem) IRoutes
|
||||
Use(_ ...HandlerFunc) IRoutes
|
||||
}
|
||||
|
||||
type Negotiate struct {
|
||||
Offered []string
|
||||
HTMLName string
|
||||
HTMLData interface{}
|
||||
JSONData interface{}
|
||||
XMLData interface{}
|
||||
YAMLData interface{}
|
||||
Data interface{}
|
||||
TOMLData interface{}
|
||||
}
|
||||
|
||||
type Param struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
type Params []Param
|
||||
|
||||
func (_ Params) ByName(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ Params) Get(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
type ResponseWriter interface {
|
||||
CloseNotify() <-chan bool
|
||||
Flush()
|
||||
Header() http.Header
|
||||
Hijack() (net.Conn, *bufio.ReadWriter, error)
|
||||
Pusher() http.Pusher
|
||||
Size() int
|
||||
Status() int
|
||||
Write(_ []byte) (int, error)
|
||||
WriteHeader(_ int)
|
||||
WriteHeaderNow()
|
||||
WriteString(_ string) (int, error)
|
||||
Written() bool
|
||||
}
|
||||
|
||||
type RouteInfo struct {
|
||||
Method string
|
||||
Path string
|
||||
Handler string
|
||||
HandlerFunc HandlerFunc
|
||||
}
|
||||
|
||||
type RouterGroup struct {
|
||||
Handlers HandlersChain
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Any(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) BasePath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) DELETE(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) GET(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Group(_ string, _ ...HandlerFunc) *RouterGroup {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) HEAD(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Handle(_ string, _ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Match(_ []string, _ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) OPTIONS(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) PATCH(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) POST(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) PUT(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Static(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) StaticFS(_ string, _ http.FileSystem) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) StaticFile(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) StaticFileFS(_ string, _ string, _ http.FileSystem) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Use(_ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
type RoutesInfo []RouteInfo
|
||||
78
go/ql/test/experimental/CWE-942/vendor/modules.txt
vendored
Normal file
78
go/ql/test/experimental/CWE-942/vendor/modules.txt
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# github.com/gin-contrib/cors v1.4.0
|
||||
## explicit
|
||||
github.com/gin-contrib/cors
|
||||
# github.com/gin-gonic/gin v1.9.1
|
||||
## explicit
|
||||
github.com/gin-gonic/gin
|
||||
# github.com/bytedance/sonic v1.9.1
|
||||
## explicit
|
||||
github.com/bytedance/sonic
|
||||
# github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311
|
||||
## explicit
|
||||
github.com/chenzhuoyu/base64x
|
||||
# github.com/gabriel-vasile/mimetype v1.4.2
|
||||
## explicit
|
||||
github.com/gabriel-vasile/mimetype
|
||||
# github.com/gin-contrib/sse v0.1.0
|
||||
## explicit
|
||||
github.com/gin-contrib/sse
|
||||
# github.com/go-playground/locales v0.14.1
|
||||
## explicit
|
||||
github.com/go-playground/locales
|
||||
# github.com/go-playground/universal-translator v0.18.1
|
||||
## explicit
|
||||
github.com/go-playground/universal-translator
|
||||
# github.com/go-playground/validator/v10 v10.14.0
|
||||
## explicit
|
||||
github.com/go-playground/validator/v10
|
||||
# github.com/goccy/go-json v0.10.2
|
||||
## explicit
|
||||
github.com/goccy/go-json
|
||||
# github.com/json-iterator/go v1.1.12
|
||||
## explicit
|
||||
github.com/json-iterator/go
|
||||
# github.com/klauspost/cpuid/v2 v2.2.4
|
||||
## explicit
|
||||
github.com/klauspost/cpuid/v2
|
||||
# github.com/leodido/go-urn v1.2.4
|
||||
## explicit
|
||||
github.com/leodido/go-urn
|
||||
# github.com/mattn/go-isatty v0.0.19
|
||||
## explicit
|
||||
github.com/mattn/go-isatty
|
||||
# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
|
||||
## explicit
|
||||
github.com/modern-go/concurrent
|
||||
# github.com/modern-go/reflect2 v1.0.2
|
||||
## explicit
|
||||
github.com/modern-go/reflect2
|
||||
# github.com/pelletier/go-toml/v2 v2.0.8
|
||||
## explicit
|
||||
github.com/pelletier/go-toml/v2
|
||||
# github.com/twitchyliquid64/golang-asm v0.15.1
|
||||
## explicit
|
||||
github.com/twitchyliquid64/golang-asm
|
||||
# github.com/ugorji/go/codec v1.2.11
|
||||
## explicit
|
||||
github.com/ugorji/go/codec
|
||||
# golang.org/x/arch v0.3.0
|
||||
## explicit
|
||||
golang.org/x/arch
|
||||
# golang.org/x/crypto v0.9.0
|
||||
## explicit
|
||||
golang.org/x/crypto
|
||||
# golang.org/x/net v0.10.0
|
||||
## explicit
|
||||
golang.org/x/net
|
||||
# golang.org/x/sys v0.8.0
|
||||
## explicit
|
||||
golang.org/x/sys
|
||||
# golang.org/x/text v0.9.0
|
||||
## explicit
|
||||
golang.org/x/text
|
||||
# google.golang.org/protobuf v1.30.0
|
||||
## explicit
|
||||
google.golang.org/protobuf
|
||||
# gopkg.in/yaml.v3 v3.0.1
|
||||
## explicit
|
||||
gopkg.in/yaml.v3
|
||||
@@ -21,5 +21,5 @@ func main() {
|
||||
// Compare with the standard dataflow support for arrays
|
||||
var b [4]string
|
||||
b[0] = source()
|
||||
sink(b[0]) // $ hasTaintFlow="index expression"
|
||||
sink(b[0]) // $ hasValueFlow="index expression"
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ edges
|
||||
| test.go:246:15:246:36 | call to GetString | test.go:249:21:249:29 | untrusted |
|
||||
| test.go:259:23:259:44 | call to GetCookie | test.go:259:16:259:45 | type conversion |
|
||||
| test.go:270:62:270:83 | call to GetCookie | test.go:270:55:270:84 | type conversion |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:278:21:278:28 | index expression |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:283:44:283:60 | selection of Filename |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:284:38:284:49 | genericFiles |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:285:37:285:48 | genericFiles |
|
||||
@@ -61,6 +62,8 @@ edges
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:301:39:301:50 | genericFiles |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:302:40:302:51 | genericFiles |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | test.go:303:39:303:50 | genericFiles |
|
||||
| test.go:276:2:276:13 | definition of genericFiles [array] | test.go:297:51:297:62 | genericFiles [array] |
|
||||
| test.go:278:21:278:28 | index expression | test.go:276:2:276:13 | definition of genericFiles [array] |
|
||||
| test.go:283:44:283:60 | selection of Filename | test.go:283:21:283:61 | call to GetDisplayString |
|
||||
| test.go:284:21:284:53 | call to SliceChunk | test.go:284:21:284:92 | selection of Filename |
|
||||
| test.go:284:38:284:49 | genericFiles | test.go:284:21:284:53 | call to SliceChunk |
|
||||
@@ -77,6 +80,7 @@ edges
|
||||
| test.go:296:21:296:61 | call to SliceMerge | test.go:296:21:296:97 | selection of Filename |
|
||||
| test.go:296:49:296:60 | genericFiles | test.go:296:21:296:61 | call to SliceMerge |
|
||||
| test.go:297:21:297:66 | call to SlicePad | test.go:297:21:297:102 | selection of Filename |
|
||||
| test.go:297:51:297:62 | genericFiles [array] | test.go:297:51:297:65 | index expression |
|
||||
| test.go:297:51:297:65 | index expression | test.go:297:21:297:66 | call to SlicePad |
|
||||
| test.go:298:21:298:66 | call to SlicePad | test.go:298:21:298:102 | selection of Filename |
|
||||
| test.go:298:36:298:47 | genericFiles | test.go:298:21:298:66 | call to SlicePad |
|
||||
@@ -177,6 +181,8 @@ nodes
|
||||
| test.go:270:55:270:84 | type conversion | semmle.label | type conversion |
|
||||
| test.go:270:62:270:83 | call to GetCookie | semmle.label | call to GetCookie |
|
||||
| test.go:275:2:275:40 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| test.go:276:2:276:13 | definition of genericFiles [array] | semmle.label | definition of genericFiles [array] |
|
||||
| test.go:278:21:278:28 | index expression | semmle.label | index expression |
|
||||
| test.go:283:21:283:61 | call to GetDisplayString | semmle.label | call to GetDisplayString |
|
||||
| test.go:283:44:283:60 | selection of Filename | semmle.label | selection of Filename |
|
||||
| test.go:284:21:284:53 | call to SliceChunk | semmle.label | call to SliceChunk |
|
||||
@@ -202,6 +208,7 @@ nodes
|
||||
| test.go:296:49:296:60 | genericFiles | semmle.label | genericFiles |
|
||||
| test.go:297:21:297:66 | call to SlicePad | semmle.label | call to SlicePad |
|
||||
| test.go:297:21:297:102 | selection of Filename | semmle.label | selection of Filename |
|
||||
| test.go:297:51:297:62 | genericFiles [array] | semmle.label | genericFiles [array] |
|
||||
| test.go:297:51:297:65 | index expression | semmle.label | index expression |
|
||||
| test.go:298:21:298:66 | call to SlicePad | semmle.label | call to SlicePad |
|
||||
| test.go:298:21:298:102 | selection of Filename | semmle.label | selection of Filename |
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Before running this, make sure there is an SSO-enabled token with package:write
|
||||
# permissions to codeql supplied via the GITHUB_TOKEN environment variable
|
||||
|
||||
AUTOMODEL_ROOT="$(readlink -f "$(dirname $0)")"
|
||||
WORKSPACE_ROOT="$AUTOMODEL_ROOT/../../.."
|
||||
GRPS="automodel,-test"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
## 0.0.7
|
||||
## 0.0.8
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.0.7
|
||||
|
||||
Support for extracting source candidates.
|
||||
## 0.0.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
## 0.0.7
|
||||
|
||||
No user-facing changes.
|
||||
Support for extracting source candidates.
|
||||
3
java/ql/automodel/src/change-notes/released/0.0.8.md
Normal file
3
java/ql/automodel/src/change-notes/released/0.0.8.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.0.8
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.7
|
||||
lastReleaseVersion: 0.0.8
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-automodel-queries
|
||||
version: 0.0.8-dev
|
||||
version: 0.0.8
|
||||
groups:
|
||||
- java
|
||||
- automodel
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.8.3
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* In `SensitiveApi.qll`, `javaApiCallablePasswordParam`, `javaApiCallableUsernameParam`, `javaApiCallableCryptoKeyParam`, and `otherApiCallableCredentialParam` predicates have been deprecated. They have been replaced with a new class `CredentialsSinkNode` and its child classes `PasswordSink`, `UsernameSink`, and `CryptoKeySink`. The predicates have been changed to using the new classes, so there may be minor changes in results relying on these predicates.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The types `java.util.SequencedCollection`, `SequencedSet` and `SequencedMap`, as well as the related `Collections.unmodifiableSequenced*` methods are now modelled. This means alerts may be raised relating to data flow through these types and methods.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The types `java.util.SequencedCollection`, `SequencedSet` and `SequencedMap`, as well as the related `Collections.unmodifiableSequenced*` methods are now modelled. This means alerts may be raised relating to data flow through these types and methods.
|
||||
@@ -1,4 +1,9 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
## 0.8.3
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* In `SensitiveApi.qll`, `javaApiCallablePasswordParam`, `javaApiCallableUsernameParam`, `javaApiCallableCryptoKeyParam`, and `otherApiCallableCredentialParam` predicates have been deprecated. They have been replaced with a new class `CredentialsSinkNode` and its child classes `PasswordSink`, `UsernameSink`, and `CryptoKeySink`. The predicates have been changed to using the new classes, so there may be minor changes in results relying on these predicates.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The types `java.util.SequencedCollection`, `SequencedSet` and `SequencedMap`, as well as the related `Collections.unmodifiableSequenced*` methods are now modelled. This means alerts may be raised relating to data flow through these types and methods.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-all
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.3
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The query `java/unsafe-deserialization` has been improved to detect insecure calls to `ObjectMessage.getObject` in JMS.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The query `java/unsafe-deserialization` has been improved to detect insecure calls to `ObjectMessage.getObject` in JMS.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user