From e992d86d38920819a6884969803f25615da0e7d6 Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Mon, 27 May 2024 09:48:10 +0000 Subject: [PATCH 1/3] Add OPML models --- .../ql/lib/semmle/python/frameworks/Opml.qll | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 python/ql/lib/semmle/python/frameworks/Opml.qll diff --git a/python/ql/lib/semmle/python/frameworks/Opml.qll b/python/ql/lib/semmle/python/frameworks/Opml.qll new file mode 100644 index 00000000000..e365f54f9ef --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Opml.qll @@ -0,0 +1,64 @@ +/** + * Provides classes modeling security-relevant aspects of the `opml` PyPI package. + * + * See + * - https://pypi.org/project/opml/ + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.Concepts +private import semmle.python.ApiGraphs + +/** + * Provides classes modeling security-relevant aspects of the `opml` PyPI package + * + * See + * - https://pypi.org/project/opml/ + */ +private module Opml { + /** + * A call to the `xpath` method of a parsed document. + * + * import opml + * root = opml.from_string(file(XML_DB).read()) + * find_text = root.xpath("`sink`") + */ + private class XPathCall extends XML::XPathExecution::Range, DataFlow::CallCfgNode { + XPathCall() { + exists(API::Node parseResult | + parseResult = API::moduleImport("opml").getMember(["parse", "from_string"]).getReturn() + | + this = parseResult.getMember("xpath").getACall() + ) + } + + override DataFlow::Node getXPath() { result = this.getArg(0) } + + override string getName() { result = "opml" } + } + + /** + * A call to either of: + * - `opml.parse` + * - `opml.from_string` + */ + private class OpmlParsing extends DataFlow::CallCfgNode, XML::XmlParsing::Range { + OpmlParsing() { + this = API::moduleImport("opml").getMember(["parse", "from_string"]).getACall() + } + + override DataFlow::Node getAnInput() { result = this.getArg(0) } + + DataFlow::Node getParserArg() { none() } + + /** + * The same as `Lxml::LxmlParsing::vulnerableTo`, because `opml` uses `lxml` for parsing. + */ + override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) { kind.isXxe() } + + override predicate mayExecuteInput() { none() } + + override DataFlow::Node getOutput() { result = this } + } +} From 34230369bc5acc7865b0195a610f508733803f4a Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Mon, 27 May 2024 09:48:49 +0000 Subject: [PATCH 2/3] Add OPML module to frameworks imports --- python/ql/lib/semmle/python/Frameworks.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index 801a51008ec..505867108f4 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -44,6 +44,7 @@ private import semmle.python.frameworks.Multidict private import semmle.python.frameworks.Mysql private import semmle.python.frameworks.MySQLdb private import semmle.python.frameworks.Numpy +private import semmle.python.frameworks.Opml private import semmle.python.frameworks.Oracledb private import semmle.python.frameworks.Pandas private import semmle.python.frameworks.Peewee From b786ea7e5fd3073497a52e5dc8de163f16a22f1f Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Mon, 27 May 2024 09:48:56 +0000 Subject: [PATCH 3/3] Add change note --- python/ql/src/change-notes/2024-05-27-opml-models.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/src/change-notes/2024-05-27-opml-models.md diff --git a/python/ql/src/change-notes/2024-05-27-opml-models.md b/python/ql/src/change-notes/2024-05-27-opml-models.md new file mode 100644 index 00000000000..1569dacd2d4 --- /dev/null +++ b/python/ql/src/change-notes/2024-05-27-opml-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added models for `opml` library. \ No newline at end of file