Python: unsafe -> mayExecuteInput

This commit is contained in:
Rasmus Lerchedahl Petersen
2020-10-15 12:56:29 +02:00
parent 00566f0eee
commit 172e058438
9 changed files with 16 additions and 16 deletions

View File

@@ -25,7 +25,7 @@ class UnsafeDeserializationConfiguration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) {
exists(Decoding d |
d.unsafe() and
d.mayExecuteInput() and
sink = d.getAnInput()
)
}

View File

@@ -56,8 +56,8 @@ class Decoding extends DataFlow::Node {
Decoding() { this = range }
/** Holds if this call is unsafe, e.g. if it may execute arbitrary code. */
predicate unsafe() { range.unsafe() }
/** Holds if this call may execute code embedded in its input. */
predicate mayExecuteInput() { range.mayExecuteInput() }
/** Gets an input that is decoded by this function. */
DataFlow::Node getAnInput() { result = range.getAnInput() }
@@ -83,8 +83,8 @@ module Decoding {
* extend `Decoding` instead.
*/
abstract class Range extends DataFlow::Node {
/** Holds if this call is unsafe, e.g. if it may execute arbitrary code. */
abstract predicate unsafe();
/** Holds if this call may execute code embedded in its input. */
abstract predicate mayExecuteInput();
/** Gets an input that is decoded by this function. */
abstract DataFlow::Node getAnInput();

View File

@@ -46,7 +46,7 @@ private module Dill {
private class DillLoadsCall extends Decoding::Range {
DillLoadsCall() { this.asCfgNode().(CallNode).getFunction() = Dill::dill::loads().asCfgNode() }
override predicate unsafe() { any() }
override predicate mayExecuteInput() { any() }
override DataFlow::Node getAnInput() {
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)

View File

@@ -365,7 +365,7 @@ private module Stdlib {
MarshalLoadsCall() { node.getFunction() = marshal::loads().asCfgNode() }
override predicate unsafe() { any() }
override predicate mayExecuteInput() { any() }
override DataFlow::Node getAnInput() { result.asCfgNode() = node.getArg(0) }
@@ -416,7 +416,7 @@ private module Stdlib {
PickleLoadsCall() { node.getFunction() = pickle::loads().asCfgNode() }
override predicate unsafe() { any() }
override predicate mayExecuteInput() { any() }
override DataFlow::Node getAnInput() { result.asCfgNode() = node.getArg(0) }

View File

@@ -83,7 +83,7 @@ private class YamlLoadCall extends Decoding::Range, DataFlow::CfgNode {
* Until 6.0 is released, we will mark `yaml.load` as possibly leading to arbitrary code execution.
* See https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation for more details.
*/
override predicate unsafe() {
override predicate mayExecuteInput() {
// If the `Loader` is not set to either `SafeLoader` or `BaseLoader` or not set at all,
// then the default loader will be used, which is not safe.
not node.getArgByName("Loader") =

View File

@@ -1,3 +1,3 @@
import dill
dill.loads(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=dill $decodeUnsafe
dill.loads(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=dill $decodeMayExecuteInput

View File

@@ -1,5 +1,5 @@
import pickle
import marshal
pickle.loads(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=pickle $decodeUnsafe
marshal.loads(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=marshal $decodeUnsafe
pickle.loads(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=pickle $decodeMayExecuteInput
marshal.loads(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=marshal $decodeMayExecuteInput

View File

@@ -1,6 +1,6 @@
import yaml
from yaml import SafeLoader
yaml.load(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=YAML $decodeUnsafe
yaml.load(payload) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=YAML $decodeMayExecuteInput
yaml.load(payload, Loader=SafeLoader) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=YAML
yaml.load(payload, Loader=yaml.BaseLoader) # $decodeInput=payload $decodeOutput=Attribute() $decodeFormat=YAML

View File

@@ -37,7 +37,7 @@ class DecodingTest extends InlineExpectationsTest {
DecodingTest() { this = "DecodingTest" }
override string getARelevantTag() {
result in ["decodeInput", "decodeOutput", "decodeFormat", "decodeUnsafe"]
result in ["decodeInput", "decodeOutput", "decodeFormat", "decodeMayExecuteInput"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
@@ -64,11 +64,11 @@ class DecodingTest extends InlineExpectationsTest {
tag = "decodeFormat"
)
or
d.unsafe() and
d.mayExecuteInput() and
location = d.getLocation() and
element = d.toString() and
value = "" and
tag = "decodeUnsafe"
tag = "decodeMayExecuteInput"
)
}
}