From 8459eec2394a23f4fc04aae8d21aab8b0b54a422 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Fri, 6 Feb 2026 09:26:49 -0500 Subject: [PATCH] Moving the SsrfSink concept into Concepts.qll, and renaming to HttpClientRequestFromModel as suggested in PR review. --- python/ql/lib/semmle/python/Concepts.qll | 29 +++++++++++++ python/ql/lib/semmle/python/Frameworks.qll | 1 - .../lib/semmle/python/frameworks/SSRFSink.qll | 42 ------------------- 3 files changed, 29 insertions(+), 43 deletions(-) delete mode 100644 python/ql/lib/semmle/python/frameworks/SSRFSink.qll diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index 1c018566cbf..76e9f4bd13f 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -15,6 +15,8 @@ private import semmle.python.security.internal.EncryptionKeySizes private import semmle.python.dataflow.new.SensitiveDataSources private import codeql.threatmodels.ThreatModels private import codeql.concepts.ConceptsShared +private import semmle.python.ApiGraphs +private import semmle.python.frameworks.data.ModelsAsData private module ConceptsShared = ConceptsMake; @@ -1656,8 +1658,35 @@ module Http { } import ConceptsShared::Http::Client as Client + // TODO: investigate whether we should treat responses to client requests as // remote-flow-sources in general. + /** + * An HTTP request modeled from `request-forgery` sinks, modeled using MaD. + */ + class HttpClientRequestFromModel extends Http::Client::Request::Range instanceof API::CallNode { + DataFlow::Node urlArg; + + HttpClientRequestFromModel() { + ( + this.getArg(_) = urlArg + or + this.getArgByName(_) = urlArg + ) and + ModelOutput::sinkNode(urlArg, "request-forgery") + } + + override DataFlow::Node getAUrlPart() { result = urlArg } + + override string getFramework() { result = "MaD" } + + override predicate disablesCertificateValidation( + DataFlow::Node disablingNode, DataFlow::Node argumentOrigin + ) { + // NOTE: if you need to define this, you have to special case it for every possible API in MaD + none() + } + } } /** diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index 532a720e80e..1c2f0a6e6d4 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -80,7 +80,6 @@ private import semmle.python.frameworks.Setuptools private import semmle.python.frameworks.Simplejson private import semmle.python.frameworks.Socketio private import semmle.python.frameworks.SqlAlchemy -private import semmle.python.frameworks.SSRFSink private import semmle.python.frameworks.Starlette private import semmle.python.frameworks.Stdlib private import semmle.python.frameworks.Streamlit diff --git a/python/ql/lib/semmle/python/frameworks/SSRFSink.qll b/python/ql/lib/semmle/python/frameworks/SSRFSink.qll deleted file mode 100644 index d732701c084..00000000000 --- a/python/ql/lib/semmle/python/frameworks/SSRFSink.qll +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Provides classes for SSRF sinks modeled using Models as Data (MaD). - */ - -private import python -private import semmle.python.Concepts -private import semmle.python.ApiGraphs -private import semmle.python.frameworks.data.ModelsAsData - -/** - * INTERNAL: Do not use. - * - * Sets up SSRF sinks as Http::Client::Request - */ -module SsrfMaDModel { - /** - * An HTTP request modeled from `request-forgery` sinks, modeled using MaD. - */ - class SsrfSink extends Http::Client::Request::Range instanceof API::CallNode { - DataFlow::Node urlArg; - - SsrfSink() { - ( - this.getArg(_) = urlArg - or - this.getArgByName(_) = urlArg - ) and - ModelOutput::sinkNode(urlArg, "request-forgery") - } - - override DataFlow::Node getAUrlPart() { result = urlArg } - - override string getFramework() { result = "MaD" } - - override predicate disablesCertificateValidation( - DataFlow::Node disablingNode, DataFlow::Node argumentOrigin - ) { - // NOTE: if you need to define this, you have to special case it for every possible API in MaD - none() - } - } -}