mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Python: Implement framework sinks
This commit is contained in:
@@ -4,4 +4,7 @@
|
||||
|
||||
private import experimental.semmle.python.frameworks.Flask
|
||||
private import experimental.semmle.python.frameworks.Django
|
||||
private import experimental.semmle.python.frameworks.Marshal
|
||||
private import experimental.semmle.python.frameworks.Pickle
|
||||
private import experimental.semmle.python.frameworks.Stdlib
|
||||
private import experimental.semmle.python.frameworks.Yaml
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `marshal` package.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.RemoteFlowSources
|
||||
private import experimental.semmle.python.Concepts
|
||||
|
||||
private module Marshal {
|
||||
/** Gets a reference to the `marshal` module. */
|
||||
DataFlow::Node marshal(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importModule("marshal")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = marshal(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `marshal` module. */
|
||||
DataFlow::Node marshal() { result = marshal(DataFlow::TypeTracker::end()) }
|
||||
|
||||
module marshal {
|
||||
/** Gets a reference to the `marshal.loads` function. */
|
||||
DataFlow::Node loads(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importMember("marshal", "loads")
|
||||
or
|
||||
t.startInAttr("loads") and
|
||||
result = marshal()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = marshal::loads(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `marshal.loads` function. */
|
||||
DataFlow::Node loads() { result = marshal::loads(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `marshal.loads`
|
||||
* See https://docs.python.org/2/library/marshal.html#marshal.load
|
||||
*/
|
||||
private class MarshalDeserialization extends DeserializationSink::Range {
|
||||
MarshalDeserialization() {
|
||||
this.asCfgNode().(CallNode).getFunction() = Marshal::marshal::loads().asCfgNode()
|
||||
}
|
||||
|
||||
override DataFlow::Node getData() { result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0) }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `pickle` package.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.RemoteFlowSources
|
||||
private import experimental.semmle.python.Concepts
|
||||
|
||||
private module Pickle {
|
||||
private string pickleModuleName() { result in ["pickle", "cPickle", "dill"] }
|
||||
|
||||
/** Gets a reference to the `pickle` module. */
|
||||
DataFlow::Node pickle(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importModule(pickleModuleName())
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = pickle(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `pickle` module. */
|
||||
DataFlow::Node pickle() { result = pickle(DataFlow::TypeTracker::end()) }
|
||||
|
||||
module pickle {
|
||||
/** Gets a reference to the `pickle.loads` function. */
|
||||
DataFlow::Node loads(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importMember(pickleModuleName(), "loads")
|
||||
or
|
||||
t.startInAttr("loads") and
|
||||
result = pickle()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = pickle::loads(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `pickle.loads` function. */
|
||||
DataFlow::Node loads() { result = pickle::loads(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `pickle.loads`
|
||||
* See https://docs.python.org/3/library/pickle.html#pickle.loads
|
||||
*/
|
||||
private class PickleDeserialization extends DeserializationSink::Range {
|
||||
PickleDeserialization() {
|
||||
this.asCfgNode().(CallNode).getFunction() = Pickle::pickle::loads().asCfgNode()
|
||||
}
|
||||
|
||||
override DataFlow::Node getData() { result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0) }
|
||||
}
|
||||
49
python/ql/src/experimental/semmle/python/frameworks/Yaml.qll
Normal file
49
python/ql/src/experimental/semmle/python/frameworks/Yaml.qll
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `yaml` package.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.RemoteFlowSources
|
||||
private import experimental.semmle.python.Concepts
|
||||
|
||||
private module Yaml {
|
||||
/** Gets a reference to the `yaml` module. */
|
||||
DataFlow::Node yaml(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importModule("yaml")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = yaml(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `yaml` module. */
|
||||
DataFlow::Node yaml() { result = yaml(DataFlow::TypeTracker::end()) }
|
||||
|
||||
module yaml {
|
||||
/** Gets a reference to the `yaml.load` function. */
|
||||
DataFlow::Node load(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importMember("yaml", "load")
|
||||
or
|
||||
t.startInAttr("load") and
|
||||
result = yaml()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = yaml::load(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `yaml.load` function. */
|
||||
DataFlow::Node load() { result = yaml::load(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `yaml.load`
|
||||
* See https://pyyaml.org/wiki/PyYAMLDocumentation
|
||||
*/
|
||||
private class YamlDeserialization extends DeserializationSink::Range {
|
||||
YamlDeserialization() {
|
||||
this.asCfgNode().(CallNode).getFunction() = Yaml::yaml::load().asCfgNode()
|
||||
}
|
||||
|
||||
override DataFlow::Node getData() { result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0) }
|
||||
}
|
||||
Reference in New Issue
Block a user