From 85d95df5ccc4aa5c7b9af7bfc1b14eb531169c7d Mon Sep 17 00:00:00 2001 From: shyun020 <127273427+shyun020@users.noreply.github.com> Date: Tue, 29 Apr 2025 00:54:39 +0900 Subject: [PATCH 1/2] Update Frameworks.qll --- 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 e6af222a615f..cc4fc9931816 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -91,3 +91,4 @@ private import semmle.python.frameworks.Urllib3 private import semmle.python.frameworks.Xmltodict private import semmle.python.frameworks.Yaml private import semmle.python.frameworks.Yarl +private import semmle.python.frameworks.Markup From 1f46f579ddc0c18015071aecdce4b5dda216ec38 Mon Sep 17 00:00:00 2001 From: shyun020 <127273427+shyun020@users.noreply.github.com> Date: Tue, 29 Apr 2025 00:57:36 +0900 Subject: [PATCH 2/2] Create Markup.qll --- .../lib/semmle/python/frameworks/Markup.qll | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 python/ql/lib/semmle/python/frameworks/Markup.qll diff --git a/python/ql/lib/semmle/python/frameworks/Markup.qll b/python/ql/lib/semmle/python/frameworks/Markup.qll new file mode 100644 index 000000000000..782f26a8c75f --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Markup.qll @@ -0,0 +1,58 @@ +/** + * Provides classes modeling security-relevant aspects of the hypothetical `markup` PyPI package + * (imported as `markup`) + * + * This models parsing functions that may process untrusted input. + */ + + private import python + private import semmle.python.dataflow.new.DataFlow + private import semmle.python.Concepts + private import semmle.python.ApiGraphs + + private module Markup { + /** + * A call to any of the parsing functions in `markup` (`parse`, `parse_document`, + * `unsafe_parse`, `unsafe_parse_document`, `safe_parse`, `safe_parse_document`) + * + * These functions may be unsafe if they parse untrusted markup content. + */ + private class MarkupParseCall extends Decoding::Range, DataFlow::CallCfgNode { + override CallNode node; + string func_name; + + MarkupParseCall() { + func_name in [ + "parse", "parse_document", "unsafe_parse", "unsafe_parse_document", + "safe_parse", "safe_parse_document", "div", "page" + ] and + this = API::moduleImport("markup").getMember(func_name).getACall() + } + + /** + * Determine whether this function call may unsafely execute input data. + * + * `unsafe_parse`, `unsafe_parse_document`, and `parse`, `parse_document` without secure settings + * are considered unsafe. + */ + override predicate mayExecuteInput() { + func_name in ["unsafe_parse", "unsafe_parse_document"] + or + func_name in ["parse", "parse_document"] and + // If no safe mode argument is set, assume unsafe + not exists(DataFlow::Node mode_arg | + mode_arg in [this.getArg(1), this.getArgByName("mode")] | + mode_arg = + API::moduleImport("markup") + .getMember(["SafeMode", "StrictMode"]) + .getAValueReachableFromSource() + ) + } + + override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("input")] } + + override DataFlow::Node getOutput() { result = this } + + override string getFormat() { result = "Markup" } + } + }