mirror of
https://github.com/github/codeql.git
synced 2026-03-17 04:56:58 +01:00
Merge branch 'master' into python-mutating-descriptor
This commit is contained in:
@@ -107,6 +107,20 @@ predicate invalid_portable_is_comparison(Compare comp, Cmpop op, ClassObject cls
|
||||
left.refersTo(obj) and right.refersTo(obj) and
|
||||
exists(ImmutableLiteral il | il.getLiteralObject() = obj)
|
||||
)
|
||||
and
|
||||
/* OK to use 'is' when comparing with a member of an enum */
|
||||
not exists(Expr left, Expr right, AstNode origin |
|
||||
comp.compares(left, op, right) and
|
||||
enum_member(origin) |
|
||||
left.refersTo(_, origin) or right.refersTo(_, origin)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate enum_member(AstNode obj) {
|
||||
exists(ClassObject cls, AssignStmt asgn |
|
||||
cls.getASuperType().getName() = "Enum" |
|
||||
cls.getPyClass() = asgn.getScope() and
|
||||
asgn.getValue() = obj
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
26
python/ql/src/Security/CWE-732/WeakFilePermissions.qhelp
Normal file
26
python/ql/src/Security/CWE-732/WeakFilePermissions.qhelp
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
When creating a file POSIX systems allow permissions to be specified
|
||||
for owner, group and others separately. Permissions should be kept as
|
||||
strict as possible, preventing access to the files contents by other users.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Restrict the file permissions of files to prevent any but the owner being able to read or write to that file
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Wikipedia:
|
||||
<a href="https://en.wikipedia.org/wiki/File_system_permissions">File system permissions</a>.
|
||||
</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
53
python/ql/src/Security/CWE-732/WeakFilePermissions.ql
Normal file
53
python/ql/src/Security/CWE-732/WeakFilePermissions.ql
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @name Overly permissive file permissions
|
||||
* @description Allowing files to be readable or writable by users other than the owner may allow sensitive information to be accessed.
|
||||
* @kind problem
|
||||
* @id py/overly-permissive-file
|
||||
* @problem.severity warning
|
||||
* @sub-severity high
|
||||
* @precision medium
|
||||
* @tags external/cwe/cwe-732
|
||||
* security
|
||||
*/
|
||||
import python
|
||||
|
||||
bindingset[p]
|
||||
int world_permission(int p) {
|
||||
result = p % 8
|
||||
}
|
||||
|
||||
bindingset[p]
|
||||
int group_permission(int p) {
|
||||
result = (p/8) % 8
|
||||
}
|
||||
|
||||
bindingset[p]
|
||||
string access(int p) {
|
||||
p%4 >= 2 and result = "writable" or
|
||||
p%4 < 2 and p != 0 and result = "readable"
|
||||
}
|
||||
|
||||
bindingset[p]
|
||||
string permissive_permission(int p) {
|
||||
result = "world " + access(world_permission(p))
|
||||
or
|
||||
world_permission(p) = 0 and result = "group " + access(group_permission(p))
|
||||
}
|
||||
|
||||
predicate chmod_call(CallNode call, FunctionObject chmod, NumericObject num) {
|
||||
any(ModuleObject os | os.getName() = "os").getAttribute("chmod") = chmod and
|
||||
chmod.getACall() = call and call.getArg(1).refersTo(num)
|
||||
}
|
||||
|
||||
predicate open_call(CallNode call, FunctionObject open, NumericObject num) {
|
||||
any(ModuleObject os | os.getName() = "os").getAttribute("open") = open and
|
||||
open.getACall() = call and call.getArg(2).refersTo(num)
|
||||
}
|
||||
|
||||
|
||||
from CallNode call, FunctionObject func, NumericObject num, string permission
|
||||
where
|
||||
(chmod_call(call, func, num) or open_call(call, func, num))
|
||||
and
|
||||
permission = permissive_permission(num.intValue())
|
||||
select call, "Overly permissive mask in " + func.getName() + " sets file to " + permission + "."
|
||||
@@ -4,6 +4,13 @@ import python
|
||||
/** A variable, either a global or local variable (including parameters) */
|
||||
class Variable extends @py_variable {
|
||||
|
||||
Variable() {
|
||||
exists(string name |
|
||||
variable(this, _, name) and
|
||||
not name = "*" and not name = "$"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the identifier (name) of this variable */
|
||||
string getId() {
|
||||
variable(this, _, result)
|
||||
|
||||
@@ -26,7 +26,11 @@ abstract class PythonSsaSourceVariable extends SsaSourceVariable {
|
||||
}
|
||||
|
||||
override string getName() {
|
||||
result = this.(Variable).getId()
|
||||
variable(this, _, result)
|
||||
}
|
||||
|
||||
Scope getScope() {
|
||||
variable(this, result, _)
|
||||
}
|
||||
|
||||
abstract ControlFlowNode getAnImplicitUse();
|
||||
@@ -46,7 +50,7 @@ abstract class PythonSsaSourceVariable extends SsaSourceVariable {
|
||||
/* Add a use at the end of scope for all variables to keep them live
|
||||
* This is necessary for taint-tracking.
|
||||
*/
|
||||
result = this.(Variable).getScope().getANormalExit()
|
||||
result = this.getScope().getANormalExit()
|
||||
}
|
||||
|
||||
override predicate hasDefiningNode(ControlFlowNode def) {
|
||||
@@ -107,7 +111,6 @@ class FunctionLocalVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
not this.(LocalVariable).getId() = "*" and
|
||||
exists(Scope s |
|
||||
s.getEntryNode() = result |
|
||||
s = this.(LocalVariable).getScope() and
|
||||
@@ -146,7 +149,6 @@ class NonLocalVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override CallNode redefinedAtCallSite() {
|
||||
not this.(LocalVariable).getId() = "*" and
|
||||
result.getScope().getScope*() = this.(LocalVariable).getScope()
|
||||
}
|
||||
|
||||
@@ -163,7 +165,6 @@ class ClassLocalVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
not this.(LocalVariable).getId() = "*" and
|
||||
result = this.(LocalVariable).getScope().getEntryNode()
|
||||
}
|
||||
|
||||
@@ -235,7 +236,6 @@ class ModuleVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
not this.(GlobalVariable).getId() = "*" and
|
||||
exists(Scope s |
|
||||
s.getEntryNode() = result |
|
||||
/* Module entry point */
|
||||
@@ -253,13 +253,6 @@ class ModuleVariable extends PythonSsaSourceVariable {
|
||||
this = scope.getOuterVariable(_) or
|
||||
this.(Variable).getAUse().getScope() = scope
|
||||
)
|
||||
or
|
||||
this.(GlobalVariable).getId() = "*" and
|
||||
exists(Scope s |
|
||||
s.getEntryNode() = result and
|
||||
this.(Variable).getScope() = s and
|
||||
exists(ImportStar is | is.getScope() = s)
|
||||
)
|
||||
}
|
||||
|
||||
override CallNode redefinedAtCallSite() { none() }
|
||||
@@ -307,6 +300,29 @@ class EscapingGlobalVariable extends ModuleVariable {
|
||||
|
||||
}
|
||||
|
||||
class SpecialSsaSourceVariable extends PythonSsaSourceVariable {
|
||||
|
||||
SpecialSsaSourceVariable() {
|
||||
variable(this, _, "*") or variable(this, _, "$")
|
||||
}
|
||||
|
||||
override ControlFlowNode getAnImplicitUse() {
|
||||
exists(ImportTimeScope s |
|
||||
result = s.getANormalExit() and this.getScope() = s
|
||||
)
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
/* Module entry point */
|
||||
this.getScope().getEntryNode() = result
|
||||
}
|
||||
|
||||
override CallNode redefinedAtCallSite() {
|
||||
result.(CallNode).getScope().getScope*() = this.(GlobalVariable).getScope()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private predicate variable_or_attribute_defined_out_of_scope(Variable v) {
|
||||
exists(NameNode n | n.defines(v) and not n.getScope() = v.getScope())
|
||||
or
|
||||
@@ -330,7 +346,7 @@ cached module SsaSource {
|
||||
|
||||
/** Holds if `v` is used as the receiver in a method call. */
|
||||
cached predicate method_call_refinement(Variable v, ControlFlowNode use, CallNode call) {
|
||||
use = v.getAUse() and
|
||||
use = v.getAUse() and
|
||||
call.getFunction().(AttrNode).getObject() = use
|
||||
}
|
||||
|
||||
@@ -387,16 +403,17 @@ cached module SsaSource {
|
||||
/** Holds if the name of `var` refers to a submodule of a package and `f` is the entry point
|
||||
* to the __init__ module of that package.
|
||||
*/
|
||||
cached predicate init_module_submodule_defn(Variable var, ControlFlowNode f) {
|
||||
cached predicate init_module_submodule_defn(PythonSsaSourceVariable var, ControlFlowNode f) {
|
||||
var instanceof GlobalVariable and
|
||||
exists(Module init |
|
||||
init.isPackageInit() and exists(init.getPackage().getSubModule(var.getId())) and
|
||||
var instanceof GlobalVariable and init.getEntryNode() = f and
|
||||
init.isPackageInit() and exists(init.getPackage().getSubModule(var.getName())) and
|
||||
init.getEntryNode() = f and
|
||||
var.getScope() = init
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the `v` is in scope at a `from import ... *` and may thus be redefined by that statement */
|
||||
cached predicate import_star_refinement(Variable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
cached predicate import_star_refinement(PythonSsaSourceVariable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
use = def and def instanceof ImportStarNode
|
||||
and
|
||||
(
|
||||
@@ -443,7 +460,7 @@ cached module SsaSource {
|
||||
|
||||
}
|
||||
|
||||
private predicate refinement(Variable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
private predicate refinement(PythonSsaSourceVariable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
SsaSource::import_star_refinement(v, use, def)
|
||||
or
|
||||
SsaSource::attribute_assignment_refinement(v, use, def)
|
||||
@@ -456,5 +473,5 @@ private predicate refinement(Variable v, ControlFlowNode use, ControlFlowNode de
|
||||
or
|
||||
SsaSource::method_call_refinement(v, use, def)
|
||||
or
|
||||
def = v.(PythonSsaSourceVariable).redefinedAtCallSite() and def = use
|
||||
def = v.redefinedAtCallSite() and def = use
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ module PointsTo {
|
||||
or
|
||||
exists(Module init |
|
||||
init = package.getInitModule().getModule() |
|
||||
not exists(Variable v | v.getScope() = init | v.getId() = name or v.getId() = "*")
|
||||
not exists(PythonSsaSourceVariable v | v.getScope() = init | v.getName() = name or v.getName() = "*")
|
||||
or
|
||||
exists(EssaVariable v, PointsToContext imp |
|
||||
v.getScope() = init and v.getName() = "*" and v.getAUse() = init.getANormalExit() |
|
||||
@@ -139,15 +139,15 @@ module PointsTo {
|
||||
var.getSourceVariable().getName() = name and
|
||||
ssa_variable_points_to(var, imp, obj, cls, orig) and
|
||||
imp.isImport() and
|
||||
not obj = undefinedVariable() |
|
||||
obj != undefinedVariable() |
|
||||
origin = origin_from_object_or_here(orig, exit)
|
||||
)
|
||||
or
|
||||
not exists(EssaVariable var | var.getAUse() = m.getANormalExit() and var.getSourceVariable().getName() = name) and
|
||||
exists(EssaVariable var, PointsToContext imp |
|
||||
var.getAUse() = m.getANormalExit() and var.getSourceVariable().getName() = "*" |
|
||||
var.getAUse() = m.getANormalExit() and var.getName() = "*" |
|
||||
SSA::ssa_variable_named_attribute_points_to(var, imp, name, obj, cls, origin) and
|
||||
imp.isImport() and not obj = undefinedVariable()
|
||||
imp.isImport() and obj != undefinedVariable()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ module PointsTo {
|
||||
/** Holds if `f` is the instantiation of an object, `cls(...)`. */
|
||||
cached predicate instantiation(CallNode f, PointsToContext context, ClassObject cls) {
|
||||
points_to(f.getFunction(), context, cls, _, _) and
|
||||
not cls = theTypeType() and
|
||||
cls != theTypeType() and
|
||||
Types::callToClassWillReturnInstance(cls)
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ module PointsTo {
|
||||
)
|
||||
or
|
||||
exists(Object obj |
|
||||
not obj = undefinedVariable() and
|
||||
obj != undefinedVariable() and
|
||||
py_module_attributes(mod.getModule(), name, obj, _, _)
|
||||
) and result = true
|
||||
or
|
||||
@@ -345,7 +345,7 @@ module PointsTo {
|
||||
private boolean package_exports_boolean(PackageObject pack, string name) {
|
||||
explicitly_imported(pack.submodule(name)) and
|
||||
(
|
||||
not exists(pack.getInitModule())
|
||||
pack.hasNoInitModule()
|
||||
or
|
||||
exists(ModuleObject init |
|
||||
pack.getInitModule() = init |
|
||||
@@ -381,9 +381,11 @@ module PointsTo {
|
||||
exists(Object value |
|
||||
points_to(guard.getLastNode(), context, value, _, _)
|
||||
|
|
||||
guard.controls(b, true) and not value.booleanValue() = false
|
||||
guard.controls(b, _) and value.maybe()
|
||||
or
|
||||
guard.controls(b, false) and not value.booleanValue() = true
|
||||
guard.controls(b, true) and value.booleanValue() = true
|
||||
or
|
||||
guard.controls(b, false) and value.booleanValue() = false
|
||||
)
|
||||
or
|
||||
/* Assume the true edge of an assert is reachable (except for assert 0/False) */
|
||||
@@ -402,9 +404,11 @@ module PointsTo {
|
||||
exists(ConditionBlock guard, Object value |
|
||||
points_to(guard.getLastNode(), context, value, _, _)
|
||||
|
|
||||
guard.controlsEdge(pred, succ, true) and not value.booleanValue() = false
|
||||
guard.controlsEdge(pred, succ, _) and value.maybe()
|
||||
or
|
||||
guard.controlsEdge(pred, succ, false) and not value.booleanValue() = true
|
||||
guard.controlsEdge(pred, succ, true) and value.booleanValue() = true
|
||||
or
|
||||
guard.controlsEdge(pred, succ, false) and value.booleanValue() = false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -553,7 +557,7 @@ module PointsTo {
|
||||
/** Gets an object pointed to by a use (of a variable). */
|
||||
private predicate use_points_to(NameNode f, PointsToContext context, Object value, ClassObject cls, ControlFlowNode origin) {
|
||||
exists(ObjectOrCfg origin_or_obj |
|
||||
not value = undefinedVariable() and
|
||||
value != undefinedVariable() and
|
||||
use_points_to_maybe_origin(f, context, value, cls, origin_or_obj) |
|
||||
origin = origin_from_object_or_here(origin_or_obj, f)
|
||||
)
|
||||
@@ -577,7 +581,7 @@ module PointsTo {
|
||||
pragma [noinline]
|
||||
private predicate class_or_module_attribute(Object obj, string name, Object value, ClassObject cls, ObjectOrCfg orig) {
|
||||
/* Normal class attributes */
|
||||
Types::class_attribute_lookup(obj, name, value, cls, orig) and not cls = theStaticMethodType() and not cls = theClassMethodType()
|
||||
Types::class_attribute_lookup(obj, name, value, cls, orig) and cls != theStaticMethodType() and cls != theClassMethodType()
|
||||
or
|
||||
/* Static methods of the class */
|
||||
exists(CallNode sm | Types::class_attribute_lookup(obj, name, sm, theStaticMethodType(), _) and sm.getArg(0) = value and cls = thePyFunctionType() and orig = value)
|
||||
@@ -853,9 +857,13 @@ module PointsTo {
|
||||
exists(Object operand |
|
||||
points_to(f.getOperand(), context, operand, _, _)
|
||||
|
|
||||
not operand.booleanValue() = true and value = theTrueObject()
|
||||
operand.maybe() and value = theTrueObject()
|
||||
or
|
||||
not operand.booleanValue() = false and value = theFalseObject()
|
||||
operand.maybe() and value = theFalseObject()
|
||||
or
|
||||
operand.booleanValue() = false and value = theTrueObject()
|
||||
or
|
||||
operand.booleanValue() = true and value = theFalseObject()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1003,17 +1011,18 @@ module PointsTo {
|
||||
pragma [noinline]
|
||||
predicate call_points_to_builtin_function(CallNode f, PointsToContext context, Object value, ClassObject cls, ControlFlowNode origin) {
|
||||
exists(BuiltinCallable b |
|
||||
not b = builtin_object("isinstance") and
|
||||
not b = builtin_object("issubclass") and
|
||||
not b = builtin_object("callable") and
|
||||
b != builtin_object("isinstance") and
|
||||
b != builtin_object("issubclass") and
|
||||
b != builtin_object("callable") and
|
||||
f = get_a_call(b, context) and
|
||||
cls = b.getAReturnType()
|
||||
) and
|
||||
f = origin and
|
||||
if cls = theNoneType() then
|
||||
value = theNoneObject()
|
||||
else
|
||||
value = f
|
||||
(
|
||||
cls = theNoneType() and value = theNoneObject()
|
||||
or
|
||||
cls != theNoneType() and value = f
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if call is to an object that always returns its first argument.
|
||||
@@ -1160,7 +1169,7 @@ module PointsTo {
|
||||
cls != theSuperType() and
|
||||
exists(Object o |
|
||||
/* list.__init__() is not a call to type.__init__() */
|
||||
not o instanceof ClassObject |
|
||||
o.notClass() |
|
||||
points_to(n.(AttrNode).getObject(name), context, o, cls, _)
|
||||
)
|
||||
or
|
||||
@@ -1203,12 +1212,14 @@ module PointsTo {
|
||||
|
||||
/** Holds if `func` implicitly returns the `None` object */
|
||||
predicate implicitly_returns(PyFunctionObject func, Object none_, ClassObject noneType) {
|
||||
noneType = theNoneType() and not func.getFunction().isGenerator() and none_ = theNoneObject() and
|
||||
(
|
||||
not exists(func.getAReturnedNode()) and exists(func.getFunction().getANormalExit())
|
||||
or
|
||||
exists(Return ret | ret.getScope() = func.getFunction() and not exists(ret.getValue()))
|
||||
)
|
||||
noneType = theNoneType() and none_ = theNoneObject() and
|
||||
exists(Function f |
|
||||
f = func.getFunction() and not f.isGenerator()
|
||||
|
|
||||
not exists(Return ret | ret.getScope() = f) and exists(f.getANormalExit())
|
||||
or
|
||||
exists(Return ret | ret.getScope() = f and not exists(ret.getValue()))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1244,7 +1255,10 @@ module PointsTo {
|
||||
* is available to all functions. Although not strictly true, this gives less surprising
|
||||
* results in practice. */
|
||||
pred_context.isMain() and pred_scope instanceof Module and succ_context.fromRuntime() and
|
||||
not strictcount(pred_var.getSourceVariable().(Variable).getAStore()) > 1
|
||||
exists(Variable v |
|
||||
v = pred_var.getSourceVariable() and
|
||||
not strictcount(v.getAStore()) > 1
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(NonEscapingGlobalVariable var |
|
||||
@@ -1571,8 +1585,8 @@ module PointsTo {
|
||||
deco = f.getADecorator().getAFlowNode() |
|
||||
exists(Object o |
|
||||
points_to(deco, _, o, _, _) |
|
||||
not o = theStaticMethodType() and
|
||||
not o = theClassMethodType()
|
||||
o != theStaticMethodType() and
|
||||
o != theClassMethodType()
|
||||
)
|
||||
or not deco instanceof NameNode
|
||||
)
|
||||
@@ -1589,7 +1603,7 @@ module PointsTo {
|
||||
|
|
||||
obj instanceof ClassObject and value = obj and cls = objcls
|
||||
or
|
||||
not obj instanceof ClassObject and value = objcls and cls = Types::class_get_meta_class(objcls)
|
||||
obj.notClass() and value = objcls and cls = Types::class_get_meta_class(objcls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,16 +1721,17 @@ module PointsTo {
|
||||
call = def.getCall() and
|
||||
var = def.getSourceVariable() and
|
||||
context.untrackableCall(call) and
|
||||
exists(PyFunctionObject modifier |
|
||||
exists(PyFunctionObject modifier, Function f |
|
||||
f = modifier.getFunction() and
|
||||
call = get_a_call(modifier, context) and
|
||||
not modifies_escaping_variable(modifier, var)
|
||||
not modifies_escaping_variable(f, var)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate modifies_escaping_variable(FunctionObject modifier, PythonSsaSourceVariable var) {
|
||||
private predicate modifies_escaping_variable(Function modifier, PythonSsaSourceVariable var) {
|
||||
exists(var.redefinedAtCallSite()) and
|
||||
modifier.getFunction().getBody().contains(var.(Variable).getAStore())
|
||||
modifier.getBody().contains(var.(Variable).getAStore())
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
@@ -2320,7 +2335,7 @@ module PointsTo {
|
||||
or
|
||||
cls = theObjectType() and result = 0
|
||||
or
|
||||
exists(builtin_base_type(cls)) and not cls = theObjectType() and result = 1
|
||||
exists(builtin_base_type(cls)) and cls != theObjectType() and result = 1
|
||||
or
|
||||
cls = theUnknownType() and result = 1
|
||||
}
|
||||
@@ -2476,7 +2491,7 @@ module PointsTo {
|
||||
/** INTERNAL -- Use `ClassObject.declaredAttribute(name). instead. */
|
||||
cached predicate class_declared_attribute(ClassObject owner, string name, Object value, ClassObject vcls, ObjectOrCfg origin) {
|
||||
/* Note that src_var must be a local variable, we aren't interested in the value that any global variable may hold */
|
||||
not value = undefinedVariable() and
|
||||
value != undefinedVariable() and
|
||||
exists(EssaVariable var, LocalVariable src_var |
|
||||
var.getSourceVariable() = src_var and
|
||||
src_var.getId() = name and
|
||||
@@ -2561,7 +2576,12 @@ module PointsTo {
|
||||
or
|
||||
exists(int i | failed_inference(class_base_type(cls, i), _) and reason = "Failed inference for base class at position " + i)
|
||||
or
|
||||
exists(int i | strictcount(class_base_type(cls, i)) > 1 and reason = "Multiple bases at position " + i)
|
||||
exists(int i, Object base1, Object base2 |
|
||||
base1 = class_base_type(cls, i) and
|
||||
base2 = class_base_type(cls, i) and
|
||||
base1 != base2 and
|
||||
reason = "Multiple bases at position " + i
|
||||
)
|
||||
or
|
||||
exists(int i, int j | class_base_type(cls, i) = class_base_type(cls, j) and i != j and reason = "Duplicate bases classes")
|
||||
or
|
||||
@@ -2581,7 +2601,7 @@ module PointsTo {
|
||||
|
||||
private ClassObject declared_meta_class(ClassObject cls) {
|
||||
exists(Object obj |
|
||||
ssa_variable_points_to(metaclass_var(cls), _, obj, _, _) |
|
||||
ssa_variable_points_to(metaclass_var(cls.getPyClass()), _, obj, _, _) |
|
||||
result = obj
|
||||
or
|
||||
obj = unknownValue() and result = theUnknownType()
|
||||
@@ -2597,28 +2617,30 @@ module PointsTo {
|
||||
|
||||
private boolean has_metaclass_var_metaclass(ClassObject cls) {
|
||||
exists(Object obj |
|
||||
ssa_variable_points_to(metaclass_var(cls), _, obj, _, _) |
|
||||
ssa_variable_points_to(metaclass_var(cls.getPyClass()), _, obj, _, _) |
|
||||
obj = undefinedVariable() and result = false
|
||||
or
|
||||
obj != undefinedVariable() and result = true
|
||||
)
|
||||
or
|
||||
not exists(metaclass_var(cls)) and result = false
|
||||
exists(Class pycls |
|
||||
pycls = cls.getPyClass() and
|
||||
not exists(metaclass_var(pycls)) and result = false
|
||||
)
|
||||
}
|
||||
|
||||
private boolean has_declared_metaclass(ClassObject cls) {
|
||||
py_cobjecttypes(cls, _) and result = true
|
||||
or
|
||||
not cls.isBuiltin() and
|
||||
result = has_six_add_metaclass(cls).booleanOr(has_metaclass_var_metaclass(cls))
|
||||
}
|
||||
|
||||
private EssaVariable metaclass_var(ClassObject cls) {
|
||||
result.getASourceUse() = cls.getPyClass().getMetaClass().getAFlowNode()
|
||||
private EssaVariable metaclass_var(Class cls) {
|
||||
result.getASourceUse() = cls.getMetaClass().getAFlowNode()
|
||||
or
|
||||
major_version() = 2 and not exists(cls.getPyClass().getMetaClass()) and
|
||||
major_version() = 2 and not exists(cls.getMetaClass()) and
|
||||
result.getName() = "__metaclass__" and
|
||||
cls.getPyClass().(ImportTimeScope).entryEdge(result.getAUse(), _)
|
||||
cls.(ImportTimeScope).entryEdge(result.getAUse(), _)
|
||||
}
|
||||
|
||||
private ClassObject get_inherited_metaclass(ClassObject cls) {
|
||||
@@ -2628,7 +2650,7 @@ module PointsTo {
|
||||
exists(Object base |
|
||||
base = class_base_type(cls, _) and
|
||||
result = theUnknownType() |
|
||||
not base instanceof ClassObject
|
||||
base.notClass()
|
||||
or
|
||||
base = theUnknownType()
|
||||
)
|
||||
|
||||
@@ -392,6 +392,10 @@ class ClassObject extends Object {
|
||||
result.getFunction().refersTo(this)
|
||||
}
|
||||
|
||||
predicate notClass() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** The 'str' class. This is the same as the 'bytes' class for
|
||||
|
||||
@@ -226,6 +226,14 @@ class PackageObject extends ModuleObject {
|
||||
result.getModule() = this.getModule().getInitModule()
|
||||
}
|
||||
|
||||
/** Holds if this package has no `__init__.py` file. */
|
||||
predicate hasNoInitModule() {
|
||||
not exists(Module m |
|
||||
m.isPackageInit() and
|
||||
m.getFile().getParent() = this.getPath()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate exportsComplete() {
|
||||
not exists(this.getInitModule())
|
||||
or
|
||||
|
||||
@@ -151,6 +151,14 @@ class Object extends @py_object {
|
||||
)
|
||||
}
|
||||
|
||||
final predicate maybe() {
|
||||
not exists(this.booleanValue())
|
||||
}
|
||||
|
||||
predicate notClass() {
|
||||
any()
|
||||
}
|
||||
|
||||
/** Holds if this object can be referred to by `longName`
|
||||
* For example, the modules `dict` in the `sys` module
|
||||
* has the long name `sys.modules` and the name `os.path.join`
|
||||
|
||||
@@ -15,16 +15,22 @@ class TornadoRequest extends TaintKind {
|
||||
result instanceof ExternalStringDictKind and
|
||||
(
|
||||
name = "headers" or
|
||||
name = "arguments" or
|
||||
name = "cookies"
|
||||
)
|
||||
or
|
||||
result instanceof ExternalStringKind and
|
||||
(
|
||||
name = "path" or
|
||||
name = "uri" or
|
||||
name = "query" or
|
||||
name = "body"
|
||||
)
|
||||
or
|
||||
result instanceof ExternalStringSequenceDictKind and
|
||||
(
|
||||
name = "arguments" or
|
||||
name = "query_arguments" or
|
||||
name = "body_arguments"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ class TwistedRequest extends TaintKind {
|
||||
or
|
||||
result instanceof ExternalStringKind and
|
||||
(
|
||||
name = "uri" or
|
||||
name = "path"
|
||||
name = "uri"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
| __init__.py:0 | *_0 = ScopeEntryDefinition |
|
||||
| __init__.py:0 | __name___0 = ScopeEntryDefinition |
|
||||
| __init__.py:0 | __package___0 = ScopeEntryDefinition |
|
||||
| __init__.py:0 | module2_0 = ImplicitSubModuleDefinition |
|
||||
| __init__.py:0 | moduleX_0 = ImplicitSubModuleDefinition |
|
||||
| __init__.py:0 | sys_0 = ScopeEntryDefinition |
|
||||
| __init__.py:1 | *_1 = ImportStarRefinement(*_0) |
|
||||
| __init__.py:1 | __name___1 = ImportStarRefinement(__name___0) |
|
||||
| __init__.py:1 | __package___1 = ImportStarRefinement(__package___0) |
|
||||
| __init__.py:1 | sys_1 = ImportStarRefinement(sys_0) |
|
||||
| __init__.py:2 | *_2 = ImportStarRefinement(*_1) |
|
||||
| __init__.py:2 | __name___2 = ImportStarRefinement(__name___1) |
|
||||
| __init__.py:2 | __package___2 = ImportStarRefinement(__package___1) |
|
||||
| __init__.py:2 | module_0 = ImportMember |
|
||||
@@ -498,7 +495,6 @@
|
||||
| h_classes.py:52 | arg1_0 = ParameterDefinition |
|
||||
| h_classes.py:52 | n_0 = FunctionExpr |
|
||||
| h_classes.py:52 | self_0 = ParameterDefinition |
|
||||
| i_imports.py:0 | *_0 = ScopeEntryDefinition |
|
||||
| i_imports.py:0 | BytesIO_0 = ScopeEntryDefinition |
|
||||
| i_imports.py:0 | StringIO_0 = ScopeEntryDefinition |
|
||||
| i_imports.py:0 | __name___0 = ScopeEntryDefinition |
|
||||
@@ -513,7 +509,6 @@
|
||||
| i_imports.py:3 | a_0 = IntegerLiteral |
|
||||
| i_imports.py:4 | b_0 = IntegerLiteral |
|
||||
| i_imports.py:5 | c_0 = IntegerLiteral |
|
||||
| i_imports.py:7 | *_1 = ImportStarRefinement(*_0) |
|
||||
| i_imports.py:7 | BytesIO_1 = ImportStarRefinement(BytesIO_0) |
|
||||
| i_imports.py:7 | StringIO_1 = ImportStarRefinement(StringIO_0) |
|
||||
| i_imports.py:7 | __name___1 = ImportStarRefinement(__name___0) |
|
||||
@@ -528,7 +523,6 @@
|
||||
| i_imports.py:13 | argv_1 = ImportMember |
|
||||
| i_imports.py:17 | sys_1 = ImportExpr |
|
||||
| i_imports.py:23 | code_1 = ImportExpr |
|
||||
| i_imports.py:27 | *_2 = ImportStarRefinement(*_1) |
|
||||
| i_imports.py:27 | __name___2 = ImportStarRefinement(__name___1) |
|
||||
| i_imports.py:27 | __package___2 = ImportStarRefinement(__package___1) |
|
||||
| i_imports.py:27 | a_2 = ImportStarRefinement(a_1) |
|
||||
|
||||
@@ -4,5 +4,5 @@ import python
|
||||
import Util
|
||||
|
||||
from EssaVariable v, EssaDefinition def
|
||||
where def = v.getDefinition()
|
||||
where def = v.getDefinition() and not v.getSourceVariable() instanceof SpecialSsaSourceVariable
|
||||
select locate(def.getLocation(), "abdefghijknrs_"), v.getRepresentation() + " = " + def.getRepresentation()
|
||||
|
||||
@@ -37,16 +37,6 @@
|
||||
| g_class_init.py:52 | self_3 | version | phi(self_1, self_2) | 'v2' | runtime |
|
||||
| g_class_init.py:52 | self_3 | version | phi(self_1, self_2) | 'v3' | runtime |
|
||||
| g_class_init.py:54 | self_1 | version | Pi(self_0) [true] | 'v2' | runtime |
|
||||
| i_imports.py:7 | *_1 | x | ImportStarRefinement(*_0) | float 1.0 | import |
|
||||
| i_imports.py:7 | *_1 | y | ImportStarRefinement(*_0) | float 2.0 | import |
|
||||
| i_imports.py:27 | *_2 | module1 | ImportStarRefinement(*_1) | Module code.test_package.module1 | import |
|
||||
| i_imports.py:27 | *_2 | module2 | ImportStarRefinement(*_1) | Module code.test_package.module2 | import |
|
||||
| i_imports.py:27 | *_2 | p | ImportStarRefinement(*_1) | int 1 | import |
|
||||
| i_imports.py:27 | *_2 | q | ImportStarRefinement(*_1) | int 2 | import |
|
||||
| i_imports.py:27 | *_2 | r | ImportStarRefinement(*_1) | Dict | import |
|
||||
| i_imports.py:27 | *_2 | s | ImportStarRefinement(*_1) | NoneType None | import |
|
||||
| i_imports.py:27 | *_2 | x | ImportStarRefinement(*_1) | float 1.0 | import |
|
||||
| i_imports.py:27 | *_2 | y | ImportStarRefinement(*_1) | float 2.0 | import |
|
||||
| k_getsetattr.py:6 | self_0 | a | ParameterDefinition | float 7.0 | code/k_getsetattr.py:15 from runtime |
|
||||
| k_getsetattr.py:6 | self_0 | c | ParameterDefinition | int 2 | code/k_getsetattr.py:15 from runtime |
|
||||
| k_getsetattr.py:7 | self_1 | a | ArgumentRefinement(self_0) | int 0 | code/k_getsetattr.py:15 from runtime |
|
||||
|
||||
@@ -5,7 +5,7 @@ private import semmle.python.pointsto.PointsToContext
|
||||
import Util
|
||||
|
||||
from EssaVariable var, string name, Object o, PointsToContext ctx
|
||||
where PointsTo::Test::ssa_variable_named_attribute_points_to(var, ctx, name, o, _, _)
|
||||
where PointsTo::Test::ssa_variable_named_attribute_points_to(var, ctx, name, o, _, _) and not var.getSourceVariable() instanceof SpecialSsaSourceVariable
|
||||
select
|
||||
locate(var.getDefinition().getLocation(), "abdfgikm"), var.getRepresentation(),
|
||||
name, var.getDefinition().getRepresentation(), repr(o), ctx
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
| __init__.py:0 | *_2 | Exit node for Module code.test_package.__init__ |
|
||||
| __init__.py:0 | __name___0 | Exit node for Module code.__init__ |
|
||||
| __init__.py:0 | __name___0 | Exit node for Module code.package.__init__ |
|
||||
| __init__.py:0 | __name___2 | Exit node for Module code.test_package.__init__ |
|
||||
@@ -12,11 +11,9 @@
|
||||
| __init__.py:0 | moduleX_1 | Exit node for Module code.package.__init__ |
|
||||
| __init__.py:0 | module_0 | Exit node for Module code.package.__init__ |
|
||||
| __init__.py:0 | sys_2 | Exit node for Module code.test_package.__init__ |
|
||||
| __init__.py:1 | *_0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:1 | __name___0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:1 | __package___0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:1 | sys_0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:2 | *_1 | ControlFlowNode for from module2 import * |
|
||||
| __init__.py:2 | __name___1 | ControlFlowNode for from module2 import * |
|
||||
| __init__.py:2 | __package___1 | ControlFlowNode for from module2 import * |
|
||||
| __init__.py:2 | sys_1 | ControlFlowNode for from module2 import * |
|
||||
|
||||
@@ -5,5 +5,5 @@ import semmle.python.pointsto.PointsTo
|
||||
import Util
|
||||
|
||||
from EssaVariable var, ControlFlowNode use
|
||||
where use = var.getAUse()
|
||||
where use = var.getAUse() and not var.getSourceVariable() instanceof SpecialSsaSourceVariable
|
||||
select locate(use.getLocation(), "abdeghjks_"), var.getRepresentation(), use.toString()
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
| test.py:0:0 | Module test | test.py:5:1 | ClassDef |
|
||||
| test.py:0:0 | Module test | test.py:11:1 | FunctionDef |
|
||||
| test.py:0:0 | Module test | test.py:14:1 | FunctionDef |
|
||||
| test.py:0:0 | Module test | test.py:17:1 | FunctionDef |
|
||||
| test.py:0:0 | Module test | test.py:51:1 | FunctionDef |
|
||||
| test.py:2:2 | deco1() | test.py:2:2 | deco1 |
|
||||
| test.py:2:2 | deco1() | test.py:3:1 | deco2()() |
|
||||
| test.py:3:1 | deco2() | test.py:3:2 | deco2 |
|
||||
| test.py:3:1 | deco2()() | test.py:3:1 | deco2() |
|
||||
| test.py:3:1 | deco2()() | test.py:4:2 | Attribute() |
|
||||
| test.py:4:2 | Attribute | test.py:4:2 | Attribute |
|
||||
| test.py:4:2 | Attribute | test.py:4:2 | deco3 |
|
||||
| test.py:4:2 | Attribute() | test.py:4:2 | Attribute |
|
||||
| test.py:4:2 | Attribute() | test.py:5:1 | ClassExpr |
|
||||
| test.py:5:1 | Class C | test.py:7:5 | FunctionDef |
|
||||
| test.py:5:1 | ClassDef | test.py:2:2 | deco1() |
|
||||
| test.py:5:1 | ClassDef | test.py:5:7 | C |
|
||||
| test.py:5:1 | ClassExpr | test.py:5:1 | Class C |
|
||||
| test.py:5:1 | ClassExpr | test.py:5:9 | Base |
|
||||
| test.py:7:5 | Function __init__ | test.py:7:18 | self |
|
||||
| test.py:7:5 | Function __init__ | test.py:8:9 | Pass |
|
||||
| test.py:7:5 | FunctionDef | test.py:7:5 | FunctionExpr |
|
||||
| test.py:7:5 | FunctionDef | test.py:7:9 | __init__ |
|
||||
| test.py:7:5 | FunctionExpr | test.py:7:5 | Function __init__ |
|
||||
| test.py:10:1 | Attribute() | test.py:10:2 | Attribute |
|
||||
| test.py:10:1 | Attribute()() | test.py:10:1 | Attribute() |
|
||||
| test.py:10:1 | Attribute()() | test.py:11:1 | FunctionExpr |
|
||||
| test.py:10:2 | Attribute | test.py:10:2 | deco4 |
|
||||
| test.py:11:1 | Function f | test.py:12:5 | Pass |
|
||||
| test.py:11:1 | FunctionDef | test.py:10:1 | Attribute()() |
|
||||
| test.py:11:1 | FunctionDef | test.py:11:5 | f |
|
||||
| test.py:11:1 | FunctionExpr | test.py:11:1 | Function f |
|
||||
| test.py:14:1 | Function f | test.py:14:7 | pos0 |
|
||||
| test.py:14:1 | Function f | test.py:14:13 | pos1 |
|
||||
| test.py:14:1 | Function f | test.py:14:20 | args |
|
||||
| test.py:14:1 | Function f | test.py:14:28 | kwargs |
|
||||
| test.py:14:1 | Function f | test.py:15:5 | Pass |
|
||||
| test.py:14:1 | FunctionDef | test.py:14:1 | FunctionExpr |
|
||||
| test.py:14:1 | FunctionDef | test.py:14:5 | f |
|
||||
| test.py:14:1 | FunctionExpr | test.py:14:1 | Function f |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:18:5 | Pass |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:19:5 | ExprStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:19:13 | Delete |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:19:20 | Pass |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:20:5 | If |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:24:5 | AssignStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:44:5 | ExprStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:45:5 | ExprStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:46:5 | ExprStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:47:5 | ExprStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:48:5 | ExprStmt |
|
||||
| test.py:17:1 | Function simple_stmts | test.py:49:5 | ExprStmt |
|
||||
| test.py:17:1 | FunctionDef | test.py:17:1 | FunctionExpr |
|
||||
| test.py:17:1 | FunctionDef | test.py:17:5 | simple_stmts |
|
||||
| test.py:17:1 | FunctionExpr | test.py:17:1 | Function simple_stmts |
|
||||
| test.py:19:5 | ExprStmt | test.py:19:5 | foo() |
|
||||
| test.py:19:5 | foo() | test.py:19:5 | foo |
|
||||
| test.py:19:13 | Delete | test.py:19:17 | x |
|
||||
| test.py:20:5 | If | test.py:20:8 | thing |
|
||||
| test.py:20:5 | If | test.py:21:9 | For |
|
||||
| test.py:21:9 | For | test.py:21:13 | a |
|
||||
| test.py:21:9 | For | test.py:21:18 | b |
|
||||
| test.py:21:9 | For | test.py:22:13 | Pass |
|
||||
| test.py:24:5 | AssignStmt | test.py:24:5 | tmp |
|
||||
| test.py:24:5 | AssignStmt | test.py:25:9 | Yield |
|
||||
| test.py:25:9 | Yield | test.py:25:15 | Tuple |
|
||||
| test.py:25:15 | Tuple | test.py:25:15 | IntegerLiteral |
|
||||
| test.py:25:15 | Tuple | test.py:26:9 | name |
|
||||
| test.py:25:15 | Tuple | test.py:27:9 | Attribute |
|
||||
| test.py:25:15 | Tuple | test.py:28:9 | BinaryExpr |
|
||||
| test.py:25:15 | Tuple | test.py:29:9 | BinaryExpr |
|
||||
| test.py:25:15 | Tuple | test.py:30:9 | BinaryExpr |
|
||||
| test.py:25:15 | Tuple | test.py:31:9 | Attribute |
|
||||
| test.py:25:15 | Tuple | test.py:32:9 | Subscript |
|
||||
| test.py:25:15 | Tuple | test.py:33:9 | Lambda |
|
||||
| test.py:25:15 | Tuple | test.py:34:9 | BoolExpr |
|
||||
| test.py:25:15 | Tuple | test.py:35:9 | Compare |
|
||||
| test.py:25:15 | Tuple | test.py:36:9 | DictComp |
|
||||
| test.py:25:15 | Tuple | test.py:37:9 | SetComp |
|
||||
| test.py:25:15 | Tuple | test.py:38:9 | ListComp |
|
||||
| test.py:25:15 | Tuple | test.py:39:9 | List |
|
||||
| test.py:25:15 | Tuple | test.py:40:9 | Dict |
|
||||
| test.py:25:15 | Tuple | test.py:41:9 | Tuple |
|
||||
| test.py:25:15 | Tuple | test.py:42:10 | Tuple |
|
||||
| test.py:27:9 | Attribute | test.py:27:9 | attr |
|
||||
| test.py:28:9 | BinaryExpr | test.py:28:9 | a |
|
||||
| test.py:28:9 | BinaryExpr | test.py:28:13 | b |
|
||||
| test.py:29:9 | BinaryExpr | test.py:29:9 | IntegerLiteral |
|
||||
| test.py:29:9 | BinaryExpr | test.py:29:13 | IntegerLiteral |
|
||||
| test.py:30:9 | BinaryExpr | test.py:30:9 | FloatLiteral |
|
||||
| test.py:30:9 | BinaryExpr | test.py:30:15 | IntegerLiteral |
|
||||
| test.py:31:9 | Attribute | test.py:31:9 | Attribute |
|
||||
| test.py:31:9 | Attribute | test.py:31:9 | a |
|
||||
| test.py:32:9 | Attribute | test.py:32:9 | a() |
|
||||
| test.py:32:9 | Subscript | test.py:32:9 | Attribute |
|
||||
| test.py:32:9 | Subscript | test.py:32:15 | c |
|
||||
| test.py:32:9 | a() | test.py:32:9 | a |
|
||||
| test.py:33:9 | Function lambda | test.py:33:16 | x |
|
||||
| test.py:33:9 | Function lambda | test.py:33:19 | Return |
|
||||
| test.py:33:9 | Lambda | test.py:33:9 | Function lambda |
|
||||
| test.py:33:19 | BinaryExpr | test.py:33:19 | x |
|
||||
| test.py:33:19 | BinaryExpr | test.py:33:21 | IntegerLiteral |
|
||||
| test.py:33:19 | Return | test.py:33:19 | BinaryExpr |
|
||||
| test.py:34:9 | BoolExpr | test.py:34:9 | p |
|
||||
| test.py:34:9 | BoolExpr | test.py:34:14 | BoolExpr |
|
||||
| test.py:34:14 | BoolExpr | test.py:34:14 | q |
|
||||
| test.py:34:14 | BoolExpr | test.py:34:20 | BinaryExpr |
|
||||
| test.py:34:20 | BinaryExpr | test.py:34:20 | r |
|
||||
| test.py:34:20 | BinaryExpr | test.py:34:24 | s |
|
||||
| test.py:35:9 | Compare | test.py:35:9 | a |
|
||||
| test.py:35:9 | Compare | test.py:35:13 | b |
|
||||
| test.py:35:9 | Compare | test.py:35:17 | c |
|
||||
| test.py:35:9 | Compare | test.py:35:22 | IntegerLiteral |
|
||||
| test.py:36:9 | DictComp | test.py:36:9 | Function dictcomp |
|
||||
| test.py:36:9 | DictComp | test.py:36:26 | x |
|
||||
| test.py:36:9 | For | test.py:36:9 | .0 |
|
||||
| test.py:36:9 | For | test.py:36:9 | For |
|
||||
| test.py:36:9 | For | test.py:36:11 | ExprStmt |
|
||||
| test.py:36:9 | For | test.py:36:21 | z |
|
||||
| test.py:36:9 | For | test.py:36:32 | y |
|
||||
| test.py:36:9 | For | test.py:36:37 | z |
|
||||
| test.py:36:9 | Function dictcomp | test.py:36:9 | .0 |
|
||||
| test.py:36:9 | Function dictcomp | test.py:36:9 | For |
|
||||
| test.py:36:11 | ExprStmt | test.py:36:11 | Yield |
|
||||
| test.py:36:11 | Tuple | test.py:36:11 | IntegerLiteral |
|
||||
| test.py:36:11 | Tuple | test.py:36:15 | y |
|
||||
| test.py:36:11 | Yield | test.py:36:11 | Tuple |
|
||||
| test.py:37:9 | For | test.py:37:9 | .0 |
|
||||
| test.py:37:9 | For | test.py:37:9 | For |
|
||||
| test.py:37:9 | For | test.py:37:12 | ExprStmt |
|
||||
| test.py:37:9 | For | test.py:37:22 | z |
|
||||
| test.py:37:9 | For | test.py:37:33 | y |
|
||||
| test.py:37:9 | For | test.py:37:38 | z |
|
||||
| test.py:37:9 | Function setcomp | test.py:37:9 | .0 |
|
||||
| test.py:37:9 | Function setcomp | test.py:37:9 | For |
|
||||
| test.py:37:9 | SetComp | test.py:37:9 | Function setcomp |
|
||||
| test.py:37:9 | SetComp | test.py:37:27 | x |
|
||||
| test.py:37:12 | ExprStmt | test.py:37:12 | Yield |
|
||||
| test.py:37:12 | Tuple | test.py:37:12 | IntegerLiteral |
|
||||
| test.py:37:12 | Tuple | test.py:37:15 | y |
|
||||
| test.py:37:12 | Yield | test.py:37:12 | Tuple |
|
||||
| test.py:38:9 | For | test.py:38:9 | .0 |
|
||||
| test.py:38:9 | For | test.py:38:11 | ExprStmt |
|
||||
| test.py:38:9 | For | test.py:38:20 | y |
|
||||
| test.py:38:9 | Function listcomp | test.py:38:9 | .0 |
|
||||
| test.py:38:9 | Function listcomp | test.py:38:9 | For |
|
||||
| test.py:38:9 | ListComp | test.py:38:9 | Function listcomp |
|
||||
| test.py:38:9 | ListComp | test.py:38:25 | z |
|
||||
| test.py:38:11 | BinaryExpr | test.py:38:11 | y |
|
||||
| test.py:38:11 | BinaryExpr | test.py:38:14 | IntegerLiteral |
|
||||
| test.py:38:11 | ExprStmt | test.py:38:11 | Yield |
|
||||
| test.py:38:11 | Yield | test.py:38:11 | BinaryExpr |
|
||||
| test.py:42:10 | Tuple | test.py:42:10 | IntegerLiteral |
|
||||
| test.py:44:5 | ExprStmt | test.py:44:5 | foo() |
|
||||
| test.py:44:5 | foo() | test.py:44:5 | foo |
|
||||
| test.py:44:5 | foo() | test.py:44:9 | IntegerLiteral |
|
||||
| test.py:45:5 | ExprStmt | test.py:45:5 | foo() |
|
||||
| test.py:45:5 | foo() | test.py:45:5 | foo |
|
||||
| test.py:45:5 | foo() | test.py:45:9 | Keyword |
|
||||
| test.py:45:9 | Keyword | test.py:45:11 | IntegerLiteral |
|
||||
| test.py:46:5 | ExprStmt | test.py:46:5 | foo() |
|
||||
| test.py:46:5 | foo() | test.py:46:5 | foo |
|
||||
| test.py:46:5 | foo() | test.py:46:9 | IntegerLiteral |
|
||||
| test.py:46:5 | foo() | test.py:46:11 | IntegerLiteral |
|
||||
| test.py:46:5 | foo() | test.py:46:13 | Starred |
|
||||
| test.py:46:13 | Starred | test.py:46:14 | t |
|
||||
| test.py:47:5 | ExprStmt | test.py:47:5 | foo() |
|
||||
| test.py:47:5 | foo() | test.py:47:5 | foo |
|
||||
| test.py:47:5 | foo() | test.py:47:9 | IntegerLiteral |
|
||||
| test.py:47:5 | foo() | test.py:47:11 | Keyword |
|
||||
| test.py:47:5 | foo() | test.py:47:15 | Starred |
|
||||
| test.py:47:11 | Keyword | test.py:47:13 | IntegerLiteral |
|
||||
| test.py:47:15 | Starred | test.py:47:16 | t |
|
||||
| test.py:48:5 | ExprStmt | test.py:48:5 | foo() |
|
||||
| test.py:48:5 | foo() | test.py:48:5 | foo |
|
||||
| test.py:48:5 | foo() | test.py:48:9 | IntegerLiteral |
|
||||
| test.py:48:5 | foo() | test.py:48:11 | Keyword |
|
||||
| test.py:48:5 | foo() | test.py:48:15 | Starred |
|
||||
| test.py:48:5 | foo() | test.py:48:18 | DictUnpacking |
|
||||
| test.py:48:11 | Keyword | test.py:48:13 | IntegerLiteral |
|
||||
| test.py:48:15 | Starred | test.py:48:16 | t |
|
||||
| test.py:48:18 | DictUnpacking | test.py:48:20 | d |
|
||||
| test.py:49:5 | ExprStmt | test.py:49:5 | f() |
|
||||
| test.py:49:5 | f() | test.py:49:5 | f |
|
||||
| test.py:49:5 | f() | test.py:49:7 | DictUnpacking |
|
||||
| test.py:49:7 | DictUnpacking | test.py:49:9 | d |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:52:5 | If |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:56:5 | While |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:61:5 | For |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:63:5 | With |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:65:5 | Try |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:69:5 | Try |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:73:5 | Try |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:77:5 | Try |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:81:5 | Try |
|
||||
| test.py:51:1 | Function compound_stmts | test.py:87:5 | Try |
|
||||
| test.py:51:1 | FunctionDef | test.py:51:1 | FunctionExpr |
|
||||
| test.py:51:1 | FunctionDef | test.py:51:5 | compound_stmts |
|
||||
| test.py:51:1 | FunctionExpr | test.py:51:1 | Function compound_stmts |
|
||||
| test.py:52:5 | If | test.py:52:8 | cond |
|
||||
| test.py:52:5 | If | test.py:53:9 | Return |
|
||||
| test.py:52:5 | If | test.py:55:9 | Raise |
|
||||
| test.py:53:9 | Return | test.py:53:16 | x |
|
||||
| test.py:55:9 | Raise | test.py:55:15 | y |
|
||||
| test.py:56:5 | While | test.py:56:11 | True |
|
||||
| test.py:56:5 | While | test.py:57:9 | If |
|
||||
| test.py:57:9 | If | test.py:57:12 | cond |
|
||||
| test.py:57:9 | If | test.py:58:13 | Break |
|
||||
| test.py:57:9 | If | test.py:60:13 | Continue |
|
||||
| test.py:61:5 | For | test.py:61:9 | x |
|
||||
| test.py:61:5 | For | test.py:61:14 | y |
|
||||
| test.py:61:5 | For | test.py:62:9 | Pass |
|
||||
| test.py:63:5 | With | test.py:63:5 | With |
|
||||
| test.py:63:5 | With | test.py:63:10 | a |
|
||||
| test.py:63:5 | With | test.py:63:15 | b |
|
||||
| test.py:63:5 | With | test.py:63:18 | c |
|
||||
| test.py:63:5 | With | test.py:63:23 | d |
|
||||
| test.py:63:5 | With | test.py:64:9 | ExprStmt |
|
||||
| test.py:64:9 | ExprStmt | test.py:64:9 | body |
|
||||
| test.py:65:5 | Try | test.py:66:9 | ExprStmt |
|
||||
| test.py:65:5 | Try | test.py:67:5 | ExceptStmt |
|
||||
| test.py:66:9 | ExprStmt | test.py:66:9 | t1 |
|
||||
| test.py:67:5 | ExceptStmt | test.py:68:9 | ExprStmt |
|
||||
| test.py:68:9 | ExprStmt | test.py:68:9 | e1 |
|
||||
| test.py:69:5 | Try | test.py:70:9 | ExprStmt |
|
||||
| test.py:69:5 | Try | test.py:71:5 | ExceptStmt |
|
||||
| test.py:70:9 | ExprStmt | test.py:70:9 | t2 |
|
||||
| test.py:71:5 | ExceptStmt | test.py:71:12 | Exception |
|
||||
| test.py:71:5 | ExceptStmt | test.py:72:9 | ExprStmt |
|
||||
| test.py:72:9 | ExprStmt | test.py:72:9 | e2 |
|
||||
| test.py:73:5 | Try | test.py:74:9 | ExprStmt |
|
||||
| test.py:73:5 | Try | test.py:75:5 | ExceptStmt |
|
||||
| test.py:74:9 | ExprStmt | test.py:74:9 | t3 |
|
||||
| test.py:75:5 | ExceptStmt | test.py:75:12 | Exception |
|
||||
| test.py:75:5 | ExceptStmt | test.py:75:25 | ex |
|
||||
| test.py:75:5 | ExceptStmt | test.py:76:9 | ExprStmt |
|
||||
| test.py:76:9 | ExprStmt | test.py:76:9 | e3 |
|
||||
| test.py:77:5 | Try | test.py:78:9 | ExprStmt |
|
||||
| test.py:77:5 | Try | test.py:80:9 | ExprStmt |
|
||||
| test.py:78:9 | ExprStmt | test.py:78:9 | t4 |
|
||||
| test.py:80:9 | ExprStmt | test.py:80:9 | f4 |
|
||||
| test.py:81:5 | Try | test.py:82:9 | ExprStmt |
|
||||
| test.py:81:5 | Try | test.py:83:5 | ExceptStmt |
|
||||
| test.py:81:5 | Try | test.py:86:9 | ExprStmt |
|
||||
| test.py:82:9 | ExprStmt | test.py:82:9 | t5 |
|
||||
| test.py:83:5 | ExceptStmt | test.py:83:12 | Exception |
|
||||
| test.py:83:5 | ExceptStmt | test.py:83:25 | ex |
|
||||
| test.py:83:5 | ExceptStmt | test.py:84:9 | ExprStmt |
|
||||
| test.py:84:9 | ExprStmt | test.py:84:9 | e5 |
|
||||
| test.py:86:9 | ExprStmt | test.py:86:9 | f5 |
|
||||
| test.py:87:5 | Try | test.py:88:9 | ExprStmt |
|
||||
| test.py:87:5 | Try | test.py:90:9 | Try |
|
||||
| test.py:88:9 | ExprStmt | test.py:88:9 | t6 |
|
||||
| test.py:90:9 | Try | test.py:91:13 | ExprStmt |
|
||||
| test.py:90:9 | Try | test.py:93:13 | ExprStmt |
|
||||
| test.py:91:13 | ExprStmt | test.py:91:13 | t7 |
|
||||
| test.py:93:13 | ExprStmt | test.py:93:13 | f7 |
|
||||
@@ -1,7 +0,0 @@
|
||||
import python
|
||||
import semmle.python.TestUtils
|
||||
|
||||
from AstNode p, AstNode c
|
||||
where p.getAChildNode() = c
|
||||
select compact_location(p), p.toString(), compact_location(c), c.toString()
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
|
||||
@deco1
|
||||
@deco2()
|
||||
@deco3.attr1.attr2
|
||||
class C(Base):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@deco4.attr()
|
||||
def f():
|
||||
pass
|
||||
|
||||
def f(pos0, pos1, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def simple_stmts():
|
||||
pass
|
||||
foo() ; del x; pass
|
||||
if thing:
|
||||
for a in b:
|
||||
pass
|
||||
#Expressions
|
||||
tmp = (
|
||||
yield 3,
|
||||
name,
|
||||
attr.attrname,
|
||||
a + b,
|
||||
3 & 4,
|
||||
3.0 * 4,
|
||||
a.b.c.d,
|
||||
a().b[c],
|
||||
lambda x: x+1,
|
||||
p or q and r ^ s,
|
||||
a < b > c in 5,
|
||||
{ 1 : y for z in x for y in z},
|
||||
{ (1, y) for z in x for y in z},
|
||||
[ y**2 for y in z ],
|
||||
[],
|
||||
{},
|
||||
(),
|
||||
(1,),
|
||||
)
|
||||
foo(1)
|
||||
foo(a=1)
|
||||
foo(1,2,*t)
|
||||
foo(1,a=1,*t)
|
||||
foo(1,a=1,*t,**d)
|
||||
f(**d)
|
||||
|
||||
def compound_stmts():
|
||||
if cond:
|
||||
return x
|
||||
else:
|
||||
raise y
|
||||
while True:
|
||||
if cond:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
for x in y:
|
||||
pass
|
||||
with a as b, c as d:
|
||||
body
|
||||
try:
|
||||
t1
|
||||
except:
|
||||
e1
|
||||
try:
|
||||
t2
|
||||
except Exception:
|
||||
e2
|
||||
try:
|
||||
t3
|
||||
except Exception as ex:
|
||||
e3
|
||||
try:
|
||||
t4
|
||||
finally:
|
||||
f4
|
||||
try:
|
||||
t5
|
||||
except Exception as ex:
|
||||
e5
|
||||
finally:
|
||||
f5
|
||||
try:
|
||||
t6
|
||||
finally:
|
||||
try:
|
||||
t7
|
||||
finally:
|
||||
f7
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
|
||||
|
||||
#ODASA-4519
|
||||
|
||||
#OK as we are using identity tests for unique objects
|
||||
V2 = "v2"
|
||||
V3 = "v3"
|
||||
@@ -85,3 +85,21 @@ def both_sides_known(zero_based="auto", query_id=False):
|
||||
if zero_based is False: # False positive here
|
||||
pass
|
||||
|
||||
#Avoid depending on enum back port for Python 2 tests:
|
||||
class Enum(object):
|
||||
pass
|
||||
|
||||
class MyEnum(Enum):
|
||||
|
||||
memberA = None
|
||||
memberB = 10
|
||||
memberC = ("Hello", "World")
|
||||
|
||||
def comp_enum(x):
|
||||
if x is MyEnum.memberA:
|
||||
return
|
||||
if x is MyEnum.memberB:
|
||||
return
|
||||
if x is MyEnum.memberC:
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
| test.py:7:1:7:19 | ControlFlowNode for Attribute() | Overly permissive mask in chmod sets file to world writable. |
|
||||
| test.py:8:1:8:20 | ControlFlowNode for Attribute() | Overly permissive mask in chmod sets file to world writable. |
|
||||
| test.py:9:1:9:21 | ControlFlowNode for Attribute() | Overly permissive mask in chmod sets file to world writable. |
|
||||
| test.py:11:1:11:21 | ControlFlowNode for Attribute() | Overly permissive mask in chmod sets file to group readable. |
|
||||
| test.py:13:1:13:28 | ControlFlowNode for Attribute() | Overly permissive mask in chmod sets file to group writable. |
|
||||
| test.py:14:1:14:19 | ControlFlowNode for Attribute() | Overly permissive mask in chmod sets file to group writable. |
|
||||
| test.py:16:1:16:25 | ControlFlowNode for Attribute() | Overly permissive mask in open sets file to world readable. |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-732/WeakFilePermissions.ql
|
||||
2
python/ql/test/query-tests/Security/CWE-732/options
Normal file
2
python/ql/test/query-tests/Security/CWE-732/options
Normal file
@@ -0,0 +1,2 @@
|
||||
semmle-extractor-options: --max-import-depth=2 -p ../lib
|
||||
optimize: true
|
||||
16
python/ql/test/query-tests/Security/CWE-732/test.py
Normal file
16
python/ql/test/query-tests/Security/CWE-732/test.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import os
|
||||
import stat
|
||||
|
||||
file = 'semmle/important_secrets'
|
||||
|
||||
|
||||
os.chmod(file, 0o7) # BAD
|
||||
os.chmod(file, 0o77) # BAD
|
||||
os.chmod(file, 0o777) # BAD
|
||||
os.chmod(file, 0o600) # GOOD
|
||||
os.chmod(file, 0o550) # BAD
|
||||
os.chmod(file, stat.S_IRWXU) # GOOD
|
||||
os.chmod(file, stat.S_IWGRP) # BAD
|
||||
os.chmod(file, 400) # BAD -- Decimal format.
|
||||
|
||||
os.open(file, 'w', 0o704) # BAD
|
||||
@@ -3,3 +3,9 @@ def system(cmd, *args, **kwargs):
|
||||
|
||||
def popen(cmd, *args, **kwargs):
|
||||
return None
|
||||
|
||||
def chmod(path, mode):
|
||||
pass
|
||||
|
||||
def open(path, flags, mode):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user