Promote template injection sinks for each framework covered

`Cheetah` was excluded as it was last updated 15 years ago and its documentation links are dead.
This commit is contained in:
Joe Farebrother
2024-11-06 16:13:36 +00:00
parent 60d8a85a9c
commit b2c13fe351
11 changed files with 229 additions and 3 deletions

View File

@@ -0,0 +1,26 @@
/**
* Provides classes modeling security-relevant aspects of the `airspeed` library.
* See https://github.com/purcell/airspeed.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
private import semmle.python.Concepts
/**
* INTERNAL: Do not use.
*
* Provides classes modeling security-relevant aspects of the `airspeed` library.
* See https://github.com/purcell/airspeed.
*/
module Airspeed {
/** A call to `airspeed.Template`. */
private class AirspeedTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
AirspeedTemplateConstruction() {
this = API::moduleImport("airspeed").getMember("Template").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}

View File

@@ -39,7 +39,7 @@ module Bottle {
ViewCallable() { this = any(BottleRouteSetup rs).getARequestHandler() }
}
/** Get methods that reprsent a route in Bottle */
/** Get methods that represent a route in Bottle */
string routeMethods() { result = ["route", "get", "post", "put", "delete", "patch"] }
private class BottleRouteSetup extends Http::Server::RouteSetup::Range, DataFlow::CallCfgNode {
@@ -171,5 +171,17 @@ module Bottle {
override predicate valueAllowsNewline() { none() }
}
}
/** Provides models for functions that construct templates. */
module Templates {
/** A call to `bottle.template`or `bottle.SimpleTemplate`. */
private class BottleTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
BottleTemplateConstruction() {
this = API::moduleImport("bottle").getMember(["template", "SimpleTemplate"]).getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}
}
}

View File

@@ -0,0 +1,26 @@
/**
* Provides classes modeling security-relevant aspects of the `chameleon` PyPI package.
* See https://chameleon.readthedocs.io/en/latest/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
private import semmle.python.Concepts
/**
* INTERNAL: Do not use.
*
* Provides classes modeling security-relevant aspects of the `chameleon` PyPI package.
* See https://chameleon.readthedocs.io/en/latest/.
*/
module Chameleon {
/** A call to `chameleon.PageTemplate`. */
private class ChameleonTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
ChameleonTemplateConstruction() {
this = API::moduleImport("chameleon").getMember("PageTemplate").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}

View File

@@ -0,0 +1,26 @@
/**
* Provides classes modeling security-relevant aspects of the `chevron` PyPI package.
* See https://pypi.org/project/chevron.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
private import semmle.python.Concepts
/**
* INTERNAL: Do not use.
*
* Provides classes modeling security-relevant aspects of the `chevron` PyPI package.
* See https://pypi.org/project/chevron.
*/
module Chevron {
/** A call to `chevron.render`. */
private class ChevronRenderConstruction extends TemplateConstruction::Range, API::CallNode {
ChevronRenderConstruction() {
this = API::moduleImport("chevron").getMember("render").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}

View File

@@ -2996,4 +2996,19 @@ module PrivateDjango {
any()
}
}
// ---------------------------------------------------------------------------
// Templates
// ---------------------------------------------------------------------------
/** A call to `django.template.Template` */
private class DjangoTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
DjangoTemplateConstruction() {
this = API::moduleImport("django").getMember("template").getMember("Template").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
// TODO: Support `from_string` on instances of `django.template.Engine`.
}

View File

@@ -721,4 +721,13 @@ module Flask {
preservesValue = false
}
}
/** A call to `flask.render_template_string` as a template construction sink. */
private class FlaskTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
FlaskTemplateConstruction() {
this = API::moduleImport("flask").getMember("render_template_string").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}

View File

@@ -0,0 +1,45 @@
/**
* Provides classes modeling security-relevant aspects of the `Genshi` PyPI package.
* See https://genshi.edgewall.org/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
private import semmle.python.Concepts
/**
* INTERNAL: Do not use.
*
* Provides classes modeling security-relevant aspects of the `Genshi` PyPI package.
* See https://genshi.edgewall.org/.
*/
module Genshi {
/** A call to `genshi.template.text.NewTextTemplate` or `genshi.template.text.OldTextTemplate`. */
private class GenshiTextTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
GenshiTextTemplateConstruction() {
this =
API::moduleImport("genshi")
.getMember("template")
.getMember("text")
.getMember(["NewTextTemplate", "OldTextTemplate"])
.getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
/** A call to `genshi.template.MarkupTemplate` */
private class GenshiMarkupTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
GenshiMarkupTemplateConstruction() {
this =
API::moduleImport("genshi")
.getMember("template")
.getMember("markup")
.getMember("MarkupTemplate")
.getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}

View File

@@ -9,9 +9,15 @@ private import semmle.python.ApiGraphs
private import semmle.python.Concepts
private import semmle.python.frameworks.data.ModelsAsData
/**
* INTERNAL: Do not use
*
* Provides classes modeling security-relevant aspects of the `jinja2` PyPI package.
* See https://jinja.palletsprojects.com.
*/
module Jinja2 {
/** A call to `jinja2.Template`. */
class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode {
private class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode {
Jinja2TemplateConstruction() {
this = API::moduleImport("jinja2").getMember("Template").getACall()
}
@@ -39,7 +45,8 @@ module Jinja2 {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/** A call to `jinja2.Environment.from_string`. */
class Jinja2FromStringConstruction extends TemplateConstruction::Range, DataFlow::MethodCallNode
private class Jinja2FromStringConstruction extends TemplateConstruction::Range,
DataFlow::MethodCallNode
{
Jinja2FromStringConstruction() { this.calls(EnvironmentClass::instance(), "from_string") }

View File

@@ -0,0 +1,26 @@
/**
* Provides classes modeling security-relevant aspects of the `Mako` PyPI package.
* See https://www.makotemplates.org/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
private import semmle.python.Concepts
/**
* INTERNAL: Do not use.
*
* Provides classes modeling security-relevant aspects of the `Mako` PyPI package.
* See https://www.makotemplates.org/.
*/
module Mako {
/** A call to `mako.template.Template`. */
private class MakoTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
MakoTemplateConstruction() {
this = API::moduleImport("mako").getMember("template").getMember("Template").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}

View File

@@ -0,0 +1,26 @@
/**
* Provides classes modeling security-relevant aspects of the `trender` PyPI package.
* See https://github.com/cesbit/trender.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
private import semmle.python.Concepts
/**
* INTERNAL: Do not use.
*
* Provides classes modeling security-relevant aspects of the `trender` PyPI package.
* See https://github.com/cesbit/trender.
*/
module TRender {
/** A call to `trender.TRender`. */
private class TRenderTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
TRenderTemplateConstruction() {
this = API::moduleImport("trender").getMember("TRender").getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
}