Skip to content

Commit 9b27fa3

Browse files
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.
1 parent 2ec513c commit 9b27fa3

File tree

11 files changed

+253
-2
lines changed

11 files changed

+253
-2
lines changed

python/ql/lib/semmle/python/Frameworks.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ private import semmle.python.frameworks.Aiohttp
1111
private import semmle.python.frameworks.Aiomysql
1212
private import semmle.python.frameworks.Aiopg
1313
private import semmle.python.frameworks.Aiosqlite
14+
private import semmle.python.frameworks.Airspeed
1415
private import semmle.python.frameworks.Anyio
1516
private import semmle.python.frameworks.Asyncpg
1617
private import semmle.python.frameworks.Baize
18+
private import semmle.python.frameworks.Bottle
1719
private import semmle.python.frameworks.BSon
1820
private import semmle.python.frameworks.CassandraDriver
21+
private import semmle.python.frameworks.Chameleon
1922
private import semmle.python.frameworks.Cherrypy
23+
private import semmle.python.frameworks.Chevron
2024
private import semmle.python.frameworks.ClickhouseDriver
2125
private import semmle.python.frameworks.Cryptodome
2226
private import semmle.python.frameworks.Cryptography
@@ -29,10 +33,12 @@ private import semmle.python.frameworks.FastApi
2933
private import semmle.python.frameworks.Flask
3034
private import semmle.python.frameworks.FlaskAdmin
3135
private import semmle.python.frameworks.FlaskSqlAlchemy
36+
private import semmle.python.frameworks.Genshi
3237
private import semmle.python.frameworks.Gradio
3338
private import semmle.python.frameworks.Httpx
3439
private import semmle.python.frameworks.Idna
3540
private import semmle.python.frameworks.Invoke
41+
private import semmle.python.frameworks.Jinja2
3642
private import semmle.python.frameworks.Jmespath
3743
private import semmle.python.frameworks.Joblib
3844
private import semmle.python.frameworks.JsonPickle
@@ -41,6 +47,7 @@ private import semmle.python.frameworks.Ldap3
4147
private import semmle.python.frameworks.Libtaxii
4248
private import semmle.python.frameworks.Libxml2
4349
private import semmle.python.frameworks.Lxml
50+
private import semmle.python.frameworks.Mako
4451
private import semmle.python.frameworks.MarkupSafe
4552
private import semmle.python.frameworks.Multidict
4653
private import semmle.python.frameworks.Mysql
@@ -77,6 +84,7 @@ private import semmle.python.frameworks.Streamlit
7784
private import semmle.python.frameworks.Toml
7885
private import semmle.python.frameworks.Torch
7986
private import semmle.python.frameworks.Tornado
87+
private import semmle.python.frameworks.TRender
8088
private import semmle.python.frameworks.Twisted
8189
private import semmle.python.frameworks.Ujson
8290
private import semmle.python.frameworks.Urllib3
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `airspeed` library.
3+
* See https://github.com/purcell/airspeed.
4+
*/
5+
6+
private import python
7+
private import semmle.python.dataflow.new.DataFlow
8+
private import semmle.python.ApiGraphs
9+
private import semmle.python.Concepts
10+
11+
/**
12+
* INTERNAL: Do not use.
13+
*
14+
* Provides classes modeling security-relevant aspects of the `airspeed` library.
15+
* See https://github.com/purcell/airspeed.
16+
*/
17+
module Airspeed {
18+
/** A call to `airspeed.Template`. */
19+
private class AirspeedTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
20+
AirspeedTemplateConstruction() {
21+
this = API::moduleImport("airspeed").getMember("Template").getACall()
22+
}
23+
24+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
25+
}
26+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `bottle` PyPI package.
3+
* See https://bottlepy.org/docs/dev/.
4+
*/
5+
6+
private import python
7+
private import semmle.python.Concepts
8+
private import semmle.python.ApiGraphs
9+
private import semmle.python.dataflow.new.RemoteFlowSources
10+
private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
11+
private import semmle.python.frameworks.Stdlib
12+
13+
/**
14+
* INTERNAL: Do not use.
15+
*
16+
* Provides models for the `bottle` PyPI package.
17+
* See https://bottlepy.org/docs/dev/.
18+
*/
19+
module Bottle {
20+
/** Gets a reference to the `bottle` module. */
21+
API::Node bottle() { result = API::moduleImport("bottle") }
22+
23+
/** Provides models for the `bottle` module. */
24+
module BottleModule {
25+
/** Provides models for functions that construct templates. */
26+
module Templates {
27+
/** A call to `bottle.template`or `bottle.SimpleTemplate`. */
28+
private class BottleTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
29+
BottleTemplateConstruction() {
30+
this = API::moduleImport("bottle").getMember(["template", "SimpleTemplate"]).getACall()
31+
}
32+
33+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
34+
}
35+
}
36+
}
37+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `chameleon` PyPI package.
3+
* See https://chameleon.readthedocs.io/en/latest/.
4+
*/
5+
6+
private import python
7+
private import semmle.python.dataflow.new.DataFlow
8+
private import semmle.python.ApiGraphs
9+
private import semmle.python.Concepts
10+
11+
/**
12+
* INTERNAL: Do not use.
13+
*
14+
* Provides classes modeling security-relevant aspects of the `chameleon` PyPI package.
15+
* See https://chameleon.readthedocs.io/en/latest/.
16+
*/
17+
module Chameleon {
18+
/** A call to `chameleon.PageTemplate`. */
19+
private class ChameleonTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
20+
ChameleonTemplateConstruction() {
21+
this = API::moduleImport("chameleon").getMember("PageTemplate").getACall()
22+
}
23+
24+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `chevron` PyPI package.
3+
* See https://pypi.org/project/chevron.
4+
*/
5+
6+
private import python
7+
private import semmle.python.dataflow.new.DataFlow
8+
private import semmle.python.ApiGraphs
9+
private import semmle.python.Concepts
10+
11+
/**
12+
* INTERNAL: Do not use.
13+
*
14+
* Provides classes modeling security-relevant aspects of the `chevron` PyPI package.
15+
* See https://pypi.org/project/chevron.
16+
*/
17+
module Chevron {
18+
/** A call to `chevron.render`. */
19+
private class ChevronRenderConstruction extends TemplateConstruction::Range, API::CallNode {
20+
ChevronRenderConstruction() {
21+
this = API::moduleImport("chevron").getMember("render").getACall()
22+
}
23+
24+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
25+
}
26+
}

python/ql/lib/semmle/python/frameworks/Django.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,4 +2996,19 @@ module PrivateDjango {
29962996
any()
29972997
}
29982998
}
2999+
3000+
// ---------------------------------------------------------------------------
3001+
// Templates
3002+
// ---------------------------------------------------------------------------
3003+
3004+
/** A call to `django.template.Template` */
3005+
private class DjangoTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
3006+
DjangoTemplateConstruction() {
3007+
this = API::moduleImport("django").getMember("template").getMember("Template").getACall()
3008+
}
3009+
3010+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
3011+
}
3012+
3013+
// TODO: Support `from_string` on instances of `django.template.Engine`.
29993014
}

python/ql/lib/semmle/python/frameworks/Flask.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,4 +721,13 @@ module Flask {
721721
preservesValue = false
722722
}
723723
}
724+
725+
/** A call to `flask.render_template_string` as a template construction sink. */
726+
private class FlaskTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
727+
FlaskTemplateConstruction() {
728+
this = API::moduleImport("flask").getMember("render_template_string").getACall()
729+
}
730+
731+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
732+
}
724733
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `Genshi` PyPI package.
3+
* See https://genshi.edgewall.org/.
4+
*/
5+
6+
private import python
7+
private import semmle.python.dataflow.new.DataFlow
8+
private import semmle.python.ApiGraphs
9+
private import semmle.python.Concepts
10+
11+
/**
12+
* INTERNAL: Do not use.
13+
*
14+
* Provides classes modeling security-relevant aspects of the `Genshi` PyPI package.
15+
* See https://genshi.edgewall.org/.
16+
*/
17+
module Genshi {
18+
/** A call to `genshi.template.text.NewTextTemplate` or `genshi.template.text.OldTextTemplate`. */
19+
private class GenshiTextTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
20+
GenshiTextTemplateConstruction() {
21+
this =
22+
API::moduleImport("genshi")
23+
.getMember("template")
24+
.getMember("text")
25+
.getMember(["NewTextTemplate", "OldTextTemplate"])
26+
.getACall()
27+
}
28+
29+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
30+
}
31+
32+
/** A call to `genshi.template.MarkupTemplate` */
33+
private class GenshiMarkupTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
34+
GenshiMarkupTemplateConstruction() {
35+
this =
36+
API::moduleImport("genshi")
37+
.getMember("template")
38+
.getMember("markup")
39+
.getMember("MarkupTemplate")
40+
.getACall()
41+
}
42+
43+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
44+
}
45+
}

python/ql/lib/semmle/python/frameworks/Jinja2.qll

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ private import semmle.python.ApiGraphs
99
private import semmle.python.Concepts
1010
private import semmle.python.frameworks.data.ModelsAsData
1111

12+
/**
13+
* INTERNAL: Do not use
14+
*
15+
* Provides classes modeling security-relevant aspects of the `jinja2` PyPI package.
16+
* See https://jinja.palletsprojects.com.
17+
*/
1218
module Jinja2 {
1319
/** A call to `jinja2.Template`. */
14-
class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode {
20+
private class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode {
1521
Jinja2TemplateConstruction() {
1622
this = API::moduleImport("jinja2").getMember("Template").getACall()
1723
}
@@ -39,7 +45,8 @@ module Jinja2 {
3945
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
4046

4147
/** A call to `jinja2.Environment.from_string`. */
42-
class Jinja2FromStringConstruction extends TemplateConstruction::Range, DataFlow::MethodCallNode
48+
private class Jinja2FromStringConstruction extends TemplateConstruction::Range,
49+
DataFlow::MethodCallNode
4350
{
4451
Jinja2FromStringConstruction() { this.calls(EnvironmentClass::instance(), "from_string") }
4552

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `Mako` PyPI package.
3+
* See https://www.makotemplates.org/.
4+
*/
5+
6+
private import python
7+
private import semmle.python.dataflow.new.DataFlow
8+
private import semmle.python.ApiGraphs
9+
private import semmle.python.Concepts
10+
11+
/**
12+
* INTERNAL: Do not use.
13+
*
14+
* Provides classes modeling security-relevant aspects of the `Mako` PyPI package.
15+
* See https://www.makotemplates.org/.
16+
*/
17+
module Mako {
18+
/** A call to `mako.template.Template`. */
19+
private class MakoTemplateConstruction extends TemplateConstruction::Range, API::CallNode {
20+
MakoTemplateConstruction() {
21+
this = API::moduleImport("mako").getMember("template").getMember("Template").getACall()
22+
}
23+
24+
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
25+
}
26+
}

0 commit comments

Comments
 (0)