mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Python: Use more common name for concept
This commit is contained in:
@@ -24,7 +24,7 @@ class UnsafeDeserializationConfiguration extends TaintTracking::Configuration {
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(UnmarshalingFunction d |
|
||||
exists(Decoding d |
|
||||
d.unsafe() and
|
||||
sink = d.getAnInput()
|
||||
)
|
||||
|
||||
@@ -40,17 +40,20 @@ module SystemCommandExecution {
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that decodes data from a binary or textual format.
|
||||
* A data-flow node that decodes data from a binary or textual format. This
|
||||
* is intended to include deserialization, unmarshalling, decoding, unpickling,
|
||||
* unzipping, decrypting, parsing etc.
|
||||
*
|
||||
* Doing so should normally preserve taint, but it can also be a problem
|
||||
* in itself, e.g. if it performs deserialization in a potentially unsafe way.
|
||||
* in itself, e.g. if it allows code execution or could result in deinal-of-service.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `UnmarshalingFunction::Range` instead.
|
||||
* extend `Decoding::Range` instead.
|
||||
*/
|
||||
class UnmarshalingFunction extends DataFlow::Node {
|
||||
UnmarshalingFunction::Range self;
|
||||
class Decoding extends DataFlow::Node {
|
||||
Decoding::Range self;
|
||||
|
||||
UnmarshalingFunction() { this = self }
|
||||
Decoding() { this = self }
|
||||
|
||||
/** Holds if this call is unsafe, e.g. if it may execute arbitrary code. */
|
||||
predicate unsafe() { self.unsafe() }
|
||||
@@ -65,15 +68,18 @@ class UnmarshalingFunction extends DataFlow::Node {
|
||||
string getFormat() { result = self.getFormat() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new unmarshaling/decoding/deserialization functions. */
|
||||
module UnmarshalingFunction {
|
||||
/** Provides a class for modeling new decoding mechanisms. */
|
||||
module Decoding {
|
||||
/**
|
||||
* A function that decodes data from a binary or textual format.
|
||||
* Doing so should normally preserve taint, but it can oalso be a problem
|
||||
* in itself, e.g. if it performs deserialization in a potentially unsafe way.
|
||||
* A data-flow node that decodes data from a binary or textual format. This
|
||||
* is intended to include deserialization, unmarshalling, decoding, unpickling,
|
||||
* unzipping, decrypting, parsing etc.
|
||||
*
|
||||
* Doing so should normally preserve taint, but it can also be a problem
|
||||
* in itself, e.g. if it allows code execution or could result in deinal-of-service.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `UnmarshalingFunction` instead.
|
||||
* extend `Decoding` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Holds if this call is unsafe, e.g. if it may execute arbitrary code. */
|
||||
|
||||
@@ -43,10 +43,8 @@ private module Dill {
|
||||
* See https://pypi.org/project/dill/ (which currently refers you
|
||||
* to https://docs.python.org/3/library/pickle.html#pickle.loads)
|
||||
*/
|
||||
private class DillLoadsCall extends UnmarshalingFunction::Range {
|
||||
DillLoadsCall() {
|
||||
this.asCfgNode().(CallNode).getFunction() = Dill::dill::loads().asCfgNode()
|
||||
}
|
||||
private class DillLoadsCall extends Decoding::Range {
|
||||
DillLoadsCall() { this.asCfgNode().(CallNode).getFunction() = Dill::dill::loads().asCfgNode() }
|
||||
|
||||
override predicate unsafe() { any() }
|
||||
|
||||
|
||||
@@ -363,10 +363,8 @@ private module Stdlib {
|
||||
* A call to `marshal.loads`
|
||||
* See https://docs.python.org/3/library/marshal.html#marshal.loads
|
||||
*/
|
||||
private class MarshalLoadsCall extends UnmarshalingFunction::Range {
|
||||
MarshalLoadsCall() {
|
||||
this.asCfgNode().(CallNode).getFunction() = marshal::loads().asCfgNode()
|
||||
}
|
||||
private class MarshalLoadsCall extends Decoding::Range {
|
||||
MarshalLoadsCall() { this.asCfgNode().(CallNode).getFunction() = marshal::loads().asCfgNode() }
|
||||
|
||||
override predicate unsafe() { any() }
|
||||
|
||||
@@ -416,10 +414,8 @@ private module Stdlib {
|
||||
* A call to `pickle.loads`
|
||||
* See https://docs.python.org/3/library/pickle.html#pickle.loads
|
||||
*/
|
||||
private class PickleLoadsCall extends UnmarshalingFunction::Range {
|
||||
PickleLoadsCall() {
|
||||
this.asCfgNode().(CallNode).getFunction() = pickle::loads().asCfgNode()
|
||||
}
|
||||
private class PickleLoadsCall extends Decoding::Range {
|
||||
PickleLoadsCall() { this.asCfgNode().(CallNode).getFunction() = pickle::loads().asCfgNode() }
|
||||
|
||||
override predicate unsafe() { any() }
|
||||
|
||||
|
||||
@@ -45,10 +45,8 @@ private module Yaml {
|
||||
* This function was briefly thought safe until new exploits were found in 2020,
|
||||
* see https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation for details.
|
||||
*/
|
||||
private class YamlDeserialization extends UnmarshalingFunction::Range {
|
||||
YamlDeserialization() {
|
||||
this.asCfgNode().(CallNode).getFunction() = Yaml::yaml::load().asCfgNode()
|
||||
}
|
||||
private class YamlLoadCall extends Decoding::Range {
|
||||
YamlLoadCall() { this.asCfgNode().(CallNode).getFunction() = Yaml::yaml::load().asCfgNode() }
|
||||
|
||||
override predicate unsafe() {
|
||||
// If the `Loader` is not set to either `SafeLoader` or `BaseLoader` or not set at all,
|
||||
|
||||
@@ -33,18 +33,18 @@ class SystemCommandExecutionTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class UnmarshalingFunctionTest extends InlineExpectationsTest {
|
||||
UnmarshalingFunctionTest() { this = "UnmarshalingFunctionTest" }
|
||||
class DecodingTest extends InlineExpectationsTest {
|
||||
DecodingTest() { this = "DecodingTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["getAnInput", "getOutput", "getFormat"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(UnmarshalingFunction ds, string unsafe |
|
||||
exists(Decoding d, string unsafe |
|
||||
(
|
||||
ds.unsafe() and unsafe = "UNSAFE_"
|
||||
d.unsafe() and unsafe = "UNSAFE_"
|
||||
or
|
||||
not ds.unsafe() and unsafe = ""
|
||||
not d.unsafe() and unsafe = ""
|
||||
) and
|
||||
(
|
||||
exists(DataFlow::Node data |
|
||||
@@ -52,19 +52,19 @@ class UnmarshalingFunctionTest extends InlineExpectationsTest {
|
||||
element = data.toString() and
|
||||
value = value_from_expr(data.asExpr()) and
|
||||
(
|
||||
data = ds.getAnInput() and
|
||||
data = d.getAnInput() and
|
||||
tag = unsafe + "getAnInput"
|
||||
or
|
||||
data = ds.getOutput() and
|
||||
data = d.getOutput() and
|
||||
tag = unsafe + "getOutput"
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(string format |
|
||||
location = ds.getLocation() and
|
||||
location = d.getLocation() and
|
||||
element = format and
|
||||
value = format and
|
||||
format = ds.getFormat() and
|
||||
format = d.getFormat() and
|
||||
tag = unsafe + "getFormat"
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user