mirror of
https://github.com/github/codeql.git
synced 2025-12-25 05:06:34 +01:00
97 lines
2.5 KiB
Plaintext
97 lines
2.5 KiB
Plaintext
/**
|
|
* @name Modification of parameter with default
|
|
* @description Modifying the default value of a parameter can lead to unexpected
|
|
* results.
|
|
* @kind path-problem
|
|
* @tags reliability
|
|
* maintainability
|
|
* @problem.severity error
|
|
* @sub-severity low
|
|
* @precision high
|
|
* @id py/modification-of-default-value
|
|
*/
|
|
|
|
import python
|
|
import semmle.python.security.Paths
|
|
|
|
predicate safe_method(string name) {
|
|
name = "count" or name = "index" or name = "copy" or name = "get" or name = "has_key" or
|
|
name = "items" or name = "keys" or name = "values" or name = "iteritems" or name = "iterkeys" or name = "itervalues"
|
|
}
|
|
|
|
/** Gets the truthiness (non emptyness) of the default of `p` if that value is mutable */
|
|
private boolean mutableDefaultValue(Parameter p) {
|
|
exists(Dict d |
|
|
p.getDefault() = d |
|
|
exists(d.getAKey()) and result = true
|
|
or
|
|
not exists(d.getAKey()) and result = false
|
|
)
|
|
or
|
|
exists(List l |
|
|
p.getDefault() = l |
|
|
exists(l.getAnElt()) and result = true
|
|
or
|
|
not exists(l.getAnElt()) and result = false
|
|
)
|
|
}
|
|
|
|
|
|
class NonEmptyMutableValue extends TaintKind {
|
|
NonEmptyMutableValue() {
|
|
this = "non-empty mutable value"
|
|
}
|
|
}
|
|
|
|
class EmptyMutableValue extends TaintKind {
|
|
EmptyMutableValue() {
|
|
this = "empty mutable value"
|
|
}
|
|
|
|
override boolean booleanValue() {
|
|
result = false
|
|
}
|
|
|
|
}
|
|
|
|
class MutableDefaultValue extends TaintSource {
|
|
|
|
boolean nonEmpty;
|
|
|
|
MutableDefaultValue() {
|
|
nonEmpty = mutableDefaultValue(this.(NameNode).getNode())
|
|
}
|
|
|
|
override string toString() {
|
|
result = "mutable default value"
|
|
}
|
|
|
|
override predicate isSourceOf(TaintKind kind) {
|
|
nonEmpty = false and kind instanceof EmptyMutableValue
|
|
or
|
|
nonEmpty = true and kind instanceof NonEmptyMutableValue
|
|
}
|
|
}
|
|
|
|
class Mutation extends TaintSink {
|
|
Mutation() {
|
|
exists(AugAssign a | a.getTarget().getAFlowNode() = this)
|
|
or
|
|
exists(Call c, Attribute a |
|
|
c.getFunc() = a |
|
|
a.getObject().getAFlowNode() = this and
|
|
not safe_method(a.getName())
|
|
)
|
|
}
|
|
|
|
override predicate sinks(TaintKind kind) {
|
|
kind instanceof EmptyMutableValue
|
|
or
|
|
kind instanceof NonEmptyMutableValue
|
|
}
|
|
}
|
|
|
|
from TaintedPathSource src, TaintedPathSink sink
|
|
where src.flowsTo(sink)
|
|
select sink.getSink(), src, sink, "$@ flows to here and is mutated.", src.getSource(), "Default value"
|