mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge branch 'main' into clean-tests
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* 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`.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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 |
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 |
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* 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.
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -5,13 +5,18 @@
|
||||
// If you add modeling of a new framework/library, remember to add it to the docs in
|
||||
// `docs/codeql/reusables/supported-frameworks.rst`
|
||||
private import semmle.python.frameworks.Aioch
|
||||
private import semmle.python.frameworks.Aiofile
|
||||
private import semmle.python.frameworks.Aiofiles
|
||||
private import semmle.python.frameworks.Aiohttp
|
||||
private import semmle.python.frameworks.Aiomysql
|
||||
private import semmle.python.frameworks.Aiopg
|
||||
private import semmle.python.frameworks.Aiosqlite
|
||||
private import semmle.python.frameworks.Anyio
|
||||
private import semmle.python.frameworks.Asyncpg
|
||||
private import semmle.python.frameworks.Baize
|
||||
private import semmle.python.frameworks.BSon
|
||||
private import semmle.python.frameworks.CassandraDriver
|
||||
private import semmle.python.frameworks.Cherrypy
|
||||
private import semmle.python.frameworks.ClickhouseDriver
|
||||
private import semmle.python.frameworks.Cryptodome
|
||||
private import semmle.python.frameworks.Cryptography
|
||||
@@ -54,6 +59,7 @@ private import semmle.python.frameworks.Requests
|
||||
private import semmle.python.frameworks.RestFramework
|
||||
private import semmle.python.frameworks.Rsa
|
||||
private import semmle.python.frameworks.RuamelYaml
|
||||
private import semmle.python.frameworks.Sanic
|
||||
private import semmle.python.frameworks.ServerLess
|
||||
private import semmle.python.frameworks.Setuptools
|
||||
private import semmle.python.frameworks.Simplejson
|
||||
|
||||
42
python/ql/lib/semmle/python/frameworks/Aiofile.qll
Normal file
42
python/ql/lib/semmle/python/frameworks/Aiofile.qll
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `aiofile` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/aiofile.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides models for the `aiofile` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/aiofile.
|
||||
*/
|
||||
private module Aiofile {
|
||||
/**
|
||||
* A call to the `async_open` function or `AIOFile` constructor from `aiofile` as a sink for Filesystem access.
|
||||
*/
|
||||
class FileResponseCall extends FileSystemAccess::Range, API::CallNode {
|
||||
string methodName;
|
||||
|
||||
FileResponseCall() {
|
||||
this = API::moduleImport("aiofile").getMember("async_open").getACall() and
|
||||
methodName = "async_open"
|
||||
or
|
||||
this = API::moduleImport("aiofile").getMember("AIOFile").getACall() and
|
||||
methodName = "AIOFile"
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = this.getParameter(0, "file_specifier").asSink() and
|
||||
methodName = "async_open"
|
||||
or
|
||||
result = this.getParameter(0, "filename").asSink() and
|
||||
methodName = "AIOFile"
|
||||
}
|
||||
}
|
||||
}
|
||||
28
python/ql/lib/semmle/python/frameworks/Aiofiles.qll
Normal file
28
python/ql/lib/semmle/python/frameworks/Aiofiles.qll
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `aiofiles` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/aiofiles.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides models for the `aiofiles` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/aiofiles.
|
||||
*/
|
||||
private module Aiofiles {
|
||||
/**
|
||||
* A call to the `open` function from `aiofiles` as a sink for Filesystem access.
|
||||
*/
|
||||
class FileResponseCall extends FileSystemAccess::Range, API::CallNode {
|
||||
FileResponseCall() { this = API::moduleImport("aiofiles").getMember("open").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0, "file").asSink() }
|
||||
}
|
||||
}
|
||||
54
python/ql/lib/semmle/python/frameworks/Anyio.qll
Normal file
54
python/ql/lib/semmle/python/frameworks/Anyio.qll
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `anyio` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/anyio.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides models for the `anyio` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/anyio.
|
||||
*/
|
||||
private module Anyio {
|
||||
/**
|
||||
* A call to the `from_path` function from `FileReadStream` or `FileWriteStream` constructors of `anyio.streams.file` as a sink for Filesystem access.
|
||||
*/
|
||||
class FileStreamCall extends FileSystemAccess::Range, API::CallNode {
|
||||
FileStreamCall() {
|
||||
this =
|
||||
API::moduleImport("anyio")
|
||||
.getMember("streams")
|
||||
.getMember("file")
|
||||
.getMember(["FileReadStream", "FileWriteStream"])
|
||||
.getMember("from_path")
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0, "path").asSink() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `Path` constructor from `anyio` as a sink for Filesystem access.
|
||||
*/
|
||||
class PathCall extends FileSystemAccess::Range, API::CallNode {
|
||||
PathCall() { this = API::moduleImport("anyio").getMember("Path").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0).asSink() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `open_file` function from `anyio` as a sink for Filesystem access.
|
||||
*/
|
||||
class OpenFileCall extends FileSystemAccess::Range, API::CallNode {
|
||||
OpenFileCall() { this = API::moduleImport("anyio").getMember("open_file").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0, "file").asSink() }
|
||||
}
|
||||
}
|
||||
35
python/ql/lib/semmle/python/frameworks/Baize.qll
Normal file
35
python/ql/lib/semmle/python/frameworks/Baize.qll
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `baize` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/baize.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
|
||||
private import semmle.python.frameworks.Stdlib
|
||||
|
||||
/**
|
||||
* Provides models for `baize` PyPI package.
|
||||
*
|
||||
* See https://pypi.org/project/baize.
|
||||
*/
|
||||
module Baize {
|
||||
/**
|
||||
* A call to the `baize.asgi.FileResponse` constructor as a sink for Filesystem access.
|
||||
*
|
||||
* it is not contained to Starlette source code but it is mentioned in documents as an alternative to Starlette FileResponse
|
||||
*/
|
||||
class BaizeFileResponseCall extends FileSystemAccess::Range, API::CallNode {
|
||||
BaizeFileResponseCall() {
|
||||
this = API::moduleImport("baize").getMember("asgi").getMember("FileResponse").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = this.getParameter(0, "filepath").asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
48
python/ql/lib/semmle/python/frameworks/Cherrypy.qll
Normal file
48
python/ql/lib/semmle/python/frameworks/Cherrypy.qll
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `cherrypy` PyPI package.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides models for the `cherrypy` PyPI package.
|
||||
* See https://cherrypy.dev/.
|
||||
*/
|
||||
private module Cherrypy {
|
||||
/**
|
||||
* Holds for an instance of `cherrypy.lib.static`
|
||||
*/
|
||||
API::Node libStatic() {
|
||||
result = API::moduleImport("cherrypy").getMember("lib").getMember("static")
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `serve_file` or `serve_download`or `staticfile` functions of `cherrypy.lib.static` as a sink for Filesystem access.
|
||||
*/
|
||||
class FileResponseCall extends FileSystemAccess::Range, API::CallNode {
|
||||
string funcName;
|
||||
|
||||
FileResponseCall() {
|
||||
this = libStatic().getMember("staticfile").getACall() and
|
||||
funcName = "staticfile"
|
||||
or
|
||||
this = libStatic().getMember("serve_file").getACall() and
|
||||
funcName = "serve_file"
|
||||
or
|
||||
this = libStatic().getMember("serve_download").getACall() and
|
||||
funcName = "serve_download"
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = this.getParameter(0, "path").asSink() and funcName = ["serve_download", "serve_file"]
|
||||
or
|
||||
result = this.getParameter(0, "filename").asSink() and
|
||||
funcName = "staticfile"
|
||||
}
|
||||
}
|
||||
}
|
||||
42
python/ql/lib/semmle/python/frameworks/Sanic.qll
Normal file
42
python/ql/lib/semmle/python/frameworks/Sanic.qll
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `sanic` PyPI package.
|
||||
* See https://sanic.dev/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides models for the `sanic` PyPI package.
|
||||
* See https://sanic.dev/.
|
||||
*/
|
||||
private module Sanic {
|
||||
/**
|
||||
* Provides models for Sanic applications (an instance of `sanic.Sanic`).
|
||||
*/
|
||||
module App {
|
||||
/** Gets a reference to a Sanic application (an instance of `sanic.Sanic`). */
|
||||
API::Node instance() { result = API::moduleImport("sanic").getMember("Sanic").getReturn() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `file` or `file_stream` functions of `sanic.response` as a sink for Filesystem access.
|
||||
*/
|
||||
class FileResponseCall extends FileSystemAccess::Range, API::CallNode {
|
||||
FileResponseCall() {
|
||||
this =
|
||||
API::moduleImport("sanic")
|
||||
.getMember("response")
|
||||
.getMember(["file", "file_stream"])
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = this.getParameter(0, "location").asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,4 +163,16 @@ module Starlette {
|
||||
|
||||
/** DEPRECATED: Alias for Url */
|
||||
deprecated module URL = Url;
|
||||
|
||||
/**
|
||||
* A call to the `starlette.responses.FileResponse` constructor as a sink for Filesystem access.
|
||||
*/
|
||||
class FileResponseCall extends FileSystemAccess::Range, API::CallNode {
|
||||
FileResponseCall() {
|
||||
this =
|
||||
API::moduleImport("starlette").getMember("responses").getMember("FileResponse").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0, "path").asSink() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1479,6 +1479,26 @@ private module StdlibPrivate {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `io.FileIO` constructor.
|
||||
* See https://docs.python.org/3/library/io.html#io.FileIO
|
||||
*/
|
||||
private class FileIOCall extends FileSystemAccess::Range, API::CallNode {
|
||||
FileIOCall() { this = API::moduleImport("io").getMember("FileIO").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0, "file").asSink() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `io.open_code` function.
|
||||
* See https://docs.python.org/3.11/library/io.html#io.open_code
|
||||
*/
|
||||
private class OpenCodeCall extends FileSystemAccess::Range, API::CallNode {
|
||||
OpenCodeCall() { this = API::moduleImport("io").getMember("open_code").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getParameter(0, "path").asSink() }
|
||||
}
|
||||
|
||||
/** Gets a reference to an open file. */
|
||||
private DataFlow::TypeTrackingNode openFile(DataFlow::TypeTracker t, FileSystemAccess openCall) {
|
||||
t.start() and
|
||||
|
||||
1
python/ql/src/Summary/options
Normal file
1
python/ql/src/Summary/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=3
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added modeling of more `FileSystemAccess` in packages `cherrypy`, `aiofile`, `aiofiles`, `anyio`, `sanic`, `starlette`, `baize`, and `io`. This will mainly affect the _Uncontrolled data used in path expression_ (`py/path-injection`) query.
|
||||
1
python/ql/test/2/library-tests/PointsTo/imports2/options
Normal file
1
python/ql/test/2/library-tests/PointsTo/imports2/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=2 --max-import-depth=2 -r package
|
||||
1
python/ql/test/2/library-tests/modules/usage/options
Normal file
1
python/ql/test/2/library-tests/modules/usage/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=2 -F script
|
||||
@@ -0,0 +1,57 @@
|
||||
| __init__.py | 1 | ControlFlowNode for ImportExpr | Module package.module | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 2 | ControlFlowNode for ImportMember | Function module | ControlFlowNode for FunctionExpr |
|
||||
| __init__.py | 2 | ControlFlowNode for module | Function module | ControlFlowNode for FunctionExpr |
|
||||
| __init__.py | 4 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 4 | ControlFlowNode for ImportMember | Module package.module2 | Entry node for Module package.module2 |
|
||||
| __init__.py | 4 | ControlFlowNode for module3 | Module package.module2 | Entry node for Module package.module2 |
|
||||
| __init__.py | 5 | ControlFlowNode for IntegerLiteral | int 7 | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 5 | ControlFlowNode for module2 | int 7 | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 6 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 6 | ControlFlowNode for ImportMember | int 7 | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 6 | ControlFlowNode for module4 | int 7 | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 7 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 7 | ControlFlowNode for ImportMember | Module package.module2 | Entry node for Module package.module2 |
|
||||
| __init__.py | 7 | ControlFlowNode for module5 | Module package.module2 | Entry node for Module package.module2 |
|
||||
| __init__.py | 8 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 8 | ControlFlowNode for ImportMember | Module package.moduleX | Entry node for Module package.moduleX |
|
||||
| __init__.py | 8 | ControlFlowNode for moduleX | Module package.moduleX | Entry node for Module package.moduleX |
|
||||
| module2.py | 1 | ControlFlowNode for IntegerLiteral | int 0 | ControlFlowNode for IntegerLiteral |
|
||||
| module2.py | 1 | ControlFlowNode for x | int 0 | ControlFlowNode for IntegerLiteral |
|
||||
| module.py | 2 | ControlFlowNode for FunctionExpr | Function module | ControlFlowNode for FunctionExpr |
|
||||
| module.py | 2 | ControlFlowNode for module | Function module | ControlFlowNode for FunctionExpr |
|
||||
| moduleX.py | 1 | ControlFlowNode for ClassExpr | class Y | ControlFlowNode for ClassExpr |
|
||||
| moduleX.py | 1 | ControlFlowNode for Y | class Y | ControlFlowNode for ClassExpr |
|
||||
| moduleX.py | 1 | ControlFlowNode for object | builtin-class object | ControlFlowNode for object |
|
||||
| test.py | 1 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| test.py | 2 | ControlFlowNode for ImportMember | Function module | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 2 | ControlFlowNode for module | Function module | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 4 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| test.py | 5 | ControlFlowNode for ImportMember | Module package.x | Entry node for Module package.x |
|
||||
| test.py | 5 | ControlFlowNode for x | Module package.x | Entry node for Module package.x |
|
||||
| test.py | 8 | ControlFlowNode for C | class C | ControlFlowNode for ClassExpr |
|
||||
| test.py | 8 | ControlFlowNode for ClassExpr | class C | ControlFlowNode for ClassExpr |
|
||||
| test.py | 8 | ControlFlowNode for object | builtin-class object | ControlFlowNode for object |
|
||||
| test.py | 10 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| test.py | 10 | ControlFlowNode for ImportMember | int 7 | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 10 | ControlFlowNode for module2 | int 7 | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 12 | ControlFlowNode for FunctionExpr | Function f | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 12 | ControlFlowNode for f | Function f | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 13 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| test.py | 13 | ControlFlowNode for ImportMember | Module package.x | Entry node for Module package.x |
|
||||
| test.py | 13 | ControlFlowNode for x | Module package.x | Entry node for Module package.x |
|
||||
| test.py | 15 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
|
||||
| test.py | 15 | ControlFlowNode for ImportMember | Module package.moduleX | Entry node for Module package.moduleX |
|
||||
| test.py | 15 | ControlFlowNode for moduleX | Module package.moduleX | Entry node for Module package.moduleX |
|
||||
| test.py | 16 | ControlFlowNode for Attribute | class Y | ControlFlowNode for ClassExpr |
|
||||
| test.py | 16 | ControlFlowNode for moduleX | Module package.moduleX | Entry node for Module package.moduleX |
|
||||
| test.py | 19 | ControlFlowNode for ImportExpr | Module tty | ControlFlowNode for ImportExpr |
|
||||
| test.py | 19 | ControlFlowNode for tty | Module tty | ControlFlowNode for ImportExpr |
|
||||
| test.py | 22 | ControlFlowNode for Attribute | Builtin-function exc_info | ControlFlowNode for from sys import * |
|
||||
| test.py | 22 | ControlFlowNode for x | Module package.x | Entry node for Module package.x |
|
||||
| test.py | 24 | ControlFlowNode for IntegerLiteral | int 0 | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 24 | ControlFlowNode for argv | int 0 | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 27 | ControlFlowNode for ImportExpr | Module sys | ControlFlowNode for ImportExpr |
|
||||
| test.py | 31 | ControlFlowNode for argv | list object | ControlFlowNode for from sys import * |
|
||||
| test.py | 33 | ControlFlowNode for ImportExpr | Module socket | ControlFlowNode for ImportExpr |
|
||||
| test.py | 34 | ControlFlowNode for timeout | builtin-class TimeoutError | ControlFlowNode for from _socket import * |
|
||||
| x.py | 2 | ControlFlowNode for ImportExpr | Module sys | ControlFlowNode for ImportExpr |
|
||||
@@ -0,0 +1,9 @@
|
||||
import python
|
||||
|
||||
from int line, ControlFlowNode f, Object o, ControlFlowNode orig
|
||||
where
|
||||
not f.getLocation().getFile().inStdlib() and
|
||||
f.refersTo(o, orig) and
|
||||
line = f.getLocation().getStartLine() and
|
||||
line != 0
|
||||
select f.getLocation().getFile().getShortName(), line, f.toString(), o.toString(), orig.toString()
|
||||
@@ -0,0 +1,57 @@
|
||||
| __init__.py | 1 | ControlFlowNode for ImportExpr | Module package.module | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 2 | ControlFlowNode for ImportMember | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| __init__.py | 2 | ControlFlowNode for module | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| __init__.py | 4 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 4 | ControlFlowNode for ImportMember | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
|
||||
| __init__.py | 4 | ControlFlowNode for module3 | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
|
||||
| __init__.py | 5 | ControlFlowNode for IntegerLiteral | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 5 | ControlFlowNode for module2 | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 6 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 6 | ControlFlowNode for ImportMember | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 6 | ControlFlowNode for module4 | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| __init__.py | 7 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 7 | ControlFlowNode for ImportMember | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
|
||||
| __init__.py | 7 | ControlFlowNode for module5 | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
|
||||
| __init__.py | 8 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| __init__.py | 8 | ControlFlowNode for ImportMember | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
|
||||
| __init__.py | 8 | ControlFlowNode for moduleX | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
|
||||
| module2.py | 1 | ControlFlowNode for IntegerLiteral | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| module2.py | 1 | ControlFlowNode for x | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| module.py | 2 | ControlFlowNode for FunctionExpr | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| module.py | 2 | ControlFlowNode for module | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| moduleX.py | 1 | ControlFlowNode for ClassExpr | class Y | builtin-class type | ControlFlowNode for ClassExpr |
|
||||
| moduleX.py | 1 | ControlFlowNode for Y | class Y | builtin-class type | ControlFlowNode for ClassExpr |
|
||||
| moduleX.py | 1 | ControlFlowNode for object | builtin-class object | builtin-class type | ControlFlowNode for object |
|
||||
| test.py | 1 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 2 | ControlFlowNode for ImportMember | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 2 | ControlFlowNode for module | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 4 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 5 | ControlFlowNode for ImportMember | Module package.x | builtin-class module | Entry node for Module package.x |
|
||||
| test.py | 5 | ControlFlowNode for x | Module package.x | builtin-class module | Entry node for Module package.x |
|
||||
| test.py | 8 | ControlFlowNode for C | class C | builtin-class type | ControlFlowNode for ClassExpr |
|
||||
| test.py | 8 | ControlFlowNode for ClassExpr | class C | builtin-class type | ControlFlowNode for ClassExpr |
|
||||
| test.py | 8 | ControlFlowNode for object | builtin-class object | builtin-class type | ControlFlowNode for object |
|
||||
| test.py | 10 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 10 | ControlFlowNode for ImportMember | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 10 | ControlFlowNode for module2 | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 12 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 12 | ControlFlowNode for f | Function f | builtin-class function | ControlFlowNode for FunctionExpr |
|
||||
| test.py | 13 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 13 | ControlFlowNode for ImportMember | Module package.x | builtin-class module | Entry node for Module package.x |
|
||||
| test.py | 13 | ControlFlowNode for x | Module package.x | builtin-class module | Entry node for Module package.x |
|
||||
| test.py | 15 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 15 | ControlFlowNode for ImportMember | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
|
||||
| test.py | 15 | ControlFlowNode for moduleX | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
|
||||
| test.py | 16 | ControlFlowNode for Attribute | class Y | builtin-class type | ControlFlowNode for ClassExpr |
|
||||
| test.py | 16 | ControlFlowNode for moduleX | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
|
||||
| test.py | 19 | ControlFlowNode for ImportExpr | Module tty | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 19 | ControlFlowNode for tty | Module tty | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 22 | ControlFlowNode for Attribute | Builtin-function exc_info | builtin-class builtin_function_or_method | ControlFlowNode for from sys import * |
|
||||
| test.py | 22 | ControlFlowNode for x | Module package.x | builtin-class module | Entry node for Module package.x |
|
||||
| test.py | 24 | ControlFlowNode for IntegerLiteral | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 24 | ControlFlowNode for argv | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
|
||||
| test.py | 27 | ControlFlowNode for ImportExpr | Module sys | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 31 | ControlFlowNode for argv | list object | builtin-class list | ControlFlowNode for from sys import * |
|
||||
| test.py | 33 | ControlFlowNode for ImportExpr | Module socket | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
| test.py | 34 | ControlFlowNode for timeout | builtin-class TimeoutError | builtin-class type | ControlFlowNode for from _socket import * |
|
||||
| x.py | 2 | ControlFlowNode for ImportExpr | Module sys | builtin-class module | ControlFlowNode for ImportExpr |
|
||||
@@ -0,0 +1,10 @@
|
||||
import python
|
||||
|
||||
from int line, ControlFlowNode f, Object o, ClassObject cls, ControlFlowNode orig
|
||||
where
|
||||
not f.getLocation().getFile().inStdlib() and
|
||||
f.refersTo(o, cls, orig) and
|
||||
line = f.getLocation().getStartLine() and
|
||||
line != 0
|
||||
select f.getLocation().getFile().getShortName(), line, f.toString(), o.toString(), cls.toString(),
|
||||
orig.toString()
|
||||
1
python/ql/test/3/library-tests/PointsTo/imports/options
Normal file
1
python/ql/test/3/library-tests/PointsTo/imports/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=3 --max-import-depth=2 -r package
|
||||
@@ -0,0 +1,15 @@
|
||||
from .module \
|
||||
import module
|
||||
|
||||
from . import module2 as module3
|
||||
module2 = 7
|
||||
from . import module2 as module4
|
||||
from . import module3 as module5
|
||||
from package import moduleX
|
||||
|
||||
#We should now have:
|
||||
#module2 = 7
|
||||
#module3 = package.module2
|
||||
#module4 = 7
|
||||
#module5 = package.module2
|
||||
#moduleX = package.moduleX
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
def module(args):
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
x = 0
|
||||
@@ -0,0 +1,2 @@
|
||||
class Y(object):
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
from sys import *
|
||||
34
python/ql/test/3/library-tests/PointsTo/imports/test.py
Normal file
34
python/ql/test/3/library-tests/PointsTo/imports/test.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from package \
|
||||
import module
|
||||
|
||||
from package \
|
||||
import x
|
||||
#Should work correctly in nested scopes as well.
|
||||
|
||||
class C(object):
|
||||
|
||||
from package import module2
|
||||
|
||||
def f(self):
|
||||
from package import x
|
||||
|
||||
from package import moduleX
|
||||
moduleX.Y
|
||||
|
||||
#A small stdlib module to test version handling.
|
||||
import tty
|
||||
|
||||
#Check imports of builtin-objects using import * with no corresponding variable.
|
||||
x.exc_info
|
||||
|
||||
argv = 0
|
||||
|
||||
try:
|
||||
from sys import *
|
||||
except:
|
||||
pass
|
||||
|
||||
argv
|
||||
|
||||
from socket import *
|
||||
timeout
|
||||
@@ -0,0 +1,6 @@
|
||||
| file://:0:0:0:0 | Module sys | isUsedAsModule |
|
||||
| file://:0:0:0:0 | Module sys.monitoring | isUsedAsModule |
|
||||
| imported.py:0:0:0:0 | Module imported | isUsedAsModule |
|
||||
| main.py:0:0:0:0 | Module main | isUsedAsScript |
|
||||
| myscript.py:0:0:0:0 | Script myscript | isUsedAsScript |
|
||||
| script:0:0:0:0 | Script script | isUsedAsScript |
|
||||
16
python/ql/test/3/library-tests/modules/usage/ModuleUsage.ql
Normal file
16
python/ql/test/3/library-tests/modules/usage/ModuleUsage.ql
Normal file
@@ -0,0 +1,16 @@
|
||||
import python
|
||||
|
||||
from ModuleValue mv, string usage
|
||||
where
|
||||
// builtin module has different name in Python 2 and 3
|
||||
not mv = Module::builtinModule() and
|
||||
(
|
||||
mv.isUsedAsModule() and usage = "isUsedAsModule"
|
||||
or
|
||||
mv.isUsedAsScript() and usage = "isUsedAsScript"
|
||||
or
|
||||
not mv.isUsedAsModule() and
|
||||
not mv.isUsedAsScript() and
|
||||
usage = "<UNKNOWN>"
|
||||
)
|
||||
select mv, usage
|
||||
6
python/ql/test/3/library-tests/modules/usage/imported.py
Normal file
6
python/ql/test/3/library-tests/modules/usage/imported.py
Normal file
@@ -0,0 +1,6 @@
|
||||
def func():
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("I could have done something interesting...")
|
||||
print("but I didn't")
|
||||
5
python/ql/test/3/library-tests/modules/usage/main.py
Normal file
5
python/ql/test/3/library-tests/modules/usage/main.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import imported
|
||||
|
||||
if __name__ == "__main__":
|
||||
imported.func()
|
||||
print('Done')
|
||||
3
python/ql/test/3/library-tests/modules/usage/myscript.py
Executable file
3
python/ql/test/3/library-tests/modules/usage/myscript.py
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
print("I'm actually a script you see ;)")
|
||||
1
python/ql/test/3/library-tests/modules/usage/options
Normal file
1
python/ql/test/3/library-tests/modules/usage/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=3 -F script
|
||||
3
python/ql/test/3/library-tests/modules/usage/script
Executable file
3
python/ql/test/3/library-tests/modules/usage/script
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
print('Under construction :)')
|
||||
@@ -1,9 +1,12 @@
|
||||
| builtin-class object | __class__ | Property __class__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __abstractmethods__ | Property __abstractmethods__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __annotations__ | Property __annotations__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __bases__ | Property __bases__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __dict__ | Property __dict__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __doc__ | Property __doc__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __module__ | Property __module__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __mro__ | Property __mro__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __qualname__ | Property __qualname__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __text_signature__ | Property __text_signature__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
| builtin-class type | __type_params__ | Property __type_params__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| 51 |
|
||||
1
python/ql/test/3/query-tests/Summary/LinesOfCode.qlref
Normal file
1
python/ql/test/3/query-tests/Summary/LinesOfCode.qlref
Normal file
@@ -0,0 +1 @@
|
||||
Summary/LinesOfCode.ql
|
||||
@@ -0,0 +1 @@
|
||||
| 11 |
|
||||
@@ -0,0 +1 @@
|
||||
Summary/LinesOfUserCode.ql
|
||||
7
python/ql/test/3/query-tests/Summary/also_python_code
Executable file
7
python/ql/test/3/query-tests/Summary/also_python_code
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# although this is actually Python code, it is not included by the extractor by default.
|
||||
|
||||
print("this is also code")
|
||||
|
||||
print("but just dummy code")
|
||||
26
python/ql/test/3/query-tests/Summary/my_file.py
Normal file
26
python/ql/test/3/query-tests/Summary/my_file.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
module level docstring
|
||||
|
||||
is not included
|
||||
"""
|
||||
# this line is not code
|
||||
|
||||
# `tty` was chosen for stability over python versions (so we don't get diffrent results
|
||||
# on different computers, that has different versions of Python).
|
||||
#
|
||||
# According to https://github.com/python/cpython/tree/master/Lib (at 2021-04-23) `tty`
|
||||
# was last changed in 2001, so chances of this being changed in the future are slim.
|
||||
import tty
|
||||
|
||||
s = """
|
||||
all these lines are code
|
||||
"""
|
||||
|
||||
print(s)
|
||||
|
||||
def func():
|
||||
"""
|
||||
this string is a doc-string. Although the module-level docstring is not considered
|
||||
code, this one apparently is ¯\_(ツ)_/¯
|
||||
"""
|
||||
pass
|
||||
5
python/ql/test/3/query-tests/Summary/not_python
Executable file
5
python/ql/test/3/query-tests/Summary/not_python
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Although this is valid python code, it should not be counted as such.
|
||||
|
||||
print("foo")
|
||||
@@ -186,14 +186,20 @@ SINK(asyncio.run(c.coro(SOURCE))) # $ MISSING: flow
|
||||
class A:
|
||||
|
||||
def __await__(self):
|
||||
# yield SOURCE -- see https://groups.google.com/g/dev-python/c/_lrrc-vp9TI?pli=1
|
||||
return (yield from asyncio.coroutine(lambda: SOURCE)())
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(SOURCE)
|
||||
yield from fut
|
||||
|
||||
async def agen(x):
|
||||
async def atest_custom_await_impl():
|
||||
a = A()
|
||||
return await a
|
||||
x = await a
|
||||
# TODO: Figure out how to actually return something from our custom __await__
|
||||
# implementation. The problem is we have to play nicely with the asyncio framework,
|
||||
# which have their own expectations on what a return value from __await__ should look
|
||||
# like.
|
||||
assert x is None
|
||||
SINK_F(x)
|
||||
|
||||
SINK(asyncio.run(agen(SOURCE))) # $ MISSING: flow
|
||||
|
||||
# Asynchronous generator functions
|
||||
# A function or method which is defined using async def and which uses the yield statement is called a asynchronous generator function. Such a function, when called, returns an asynchronous iterator object which can be used in an async for statement to execute the body of the function.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
semmle-extractor-options: --max-import-depth=2 -r package
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,4 @@
|
||||
from aiofile import async_open, AIOFile
|
||||
|
||||
AIOFile("file", 'r') # $ getAPathArgument="file"
|
||||
async_open("file", "r") # $ getAPathArgument="file"
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,3 @@
|
||||
import aiofiles
|
||||
|
||||
aiofiles.open("file", mode='r') # $ getAPathArgument="file"
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,8 @@
|
||||
import anyio
|
||||
from anyio.streams.file import FileReadStream, FileWriteStream
|
||||
from anyio import Path
|
||||
|
||||
anyio.open_file("file", 'r') # $ getAPathArgument="file"
|
||||
FileReadStream.from_path("file") # $ getAPathArgument="file"
|
||||
FileWriteStream.from_path("file") # $ getAPathArgument="file"
|
||||
Path("file") # $ getAPathArgument="file"
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user