Python : Add query to detect Server Side Template Injection

This commit is contained in:
Porcupiney Hairs
2020-05-04 01:56:37 +05:30
parent 2e5af67626
commit 49df4169cf
64 changed files with 918 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
/**
* @name Server Side Template Injection
* @description Using user-controlled data to create a template can cause security issues.
* @kind path-problem
* @problem.severity error
* @precision high
* @id py/template-injection
* @tags security
* external/cwe/cwe-074
*/
import python
import semmle.python.security.Paths
/* Sources */
import semmle.python.web.HttpRequest
/* Sinks */
import experimental.semmle.python.templates.Ssti
class TemplateInjectionConfiguration extends TaintTracking::Configuration {
TemplateInjectionConfiguration() { this = "Template injection configuration" }
override predicate isSource(TaintTracking::Source source) {
source instanceof HttpRequestTaintSource
}
override predicate isSink(TaintTracking::Sink sink) { sink instanceof SSTISink }
}
from TemplateInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink
where config.hasFlowPath(src, sink)
select sink.getSink(), src, sink, "This Template depends on $@.", src.getSource(),
"a user-provided value"

View File

@@ -0,0 +1,27 @@
/** Provides classes which model the `airspeed` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `airspeed.Template` */
ClassValue theAirspeedTemplateClass() { result = Value::named("airspeed.Template") }
/**
* Sink representing the `airspeed.Template` class instantiation argument.
*
* import airspeed
* temp = airspeed.Template(`"sink"`)
*/
class AirspeedTemplateSink extends SSTISink {
override string toString() { result = "argument to airspeed.Template()" }
AirspeedTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theAirspeedTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,46 @@
/** Provides classes which model the `bottle` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `bottle.SimpleTemplate` */
ClassValue theBottleSimpleTemplateClass() { result = Value::named("bottle.SimpleTemplate") }
/**
* Sink representing the `bottle.SimpleTemplate` class instantiation argument.
*
* from bottle import SimpleTemplate
* template = SimpleTemplate(`sink`)
*/
class BottleSimpleTemplateSink extends SSTISink {
override string toString() { result = "argument to bottle.SimpleTemplate()" }
BottleSimpleTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theBottleSimpleTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* Sink representing the `bottle.template` function call argument.
*
* from bottle import template
* tmp = template(`sink`)
*/
class BottleTemplateSink extends SSTISink {
override string toString() { result = "argument to bottle.template()" }
BottleTemplateSink() {
exists(CallNode call |
call.getFunction() = theBottleModule().attr("template").getAReference() and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,27 @@
/** Provides classes which model the `Chameleon` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `chameleon.PageTemplate` */
ClassValue theChameleonPageTemplateClass() { result = Value::named("chameleon.PageTemplate") }
/**
* Sink representing the `chameleon.PageTemplate` class instantiation argument.
*
* from chameleon import PageTemplate
* template = PageTemplate(`sink`)
*/
class ChameleonTemplateSink extends SSTISink {
override string toString() { result = "argument to Chameleon.PageTemplate()" }
ChameleonTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theChameleonPageTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,37 @@
/** Provides classes which model the `Cheetah3` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `Cheetah.Template.Template` */
ClassValue theCheetahTemplateClass() { result = Value::named("Cheetah.Template.Template") }
/**
* Sink representing the instantiation argument of any class which derives from
* the `Cheetah.Template.Template` class .
*
* from Cheetah.Template import Template
* class Template3(Template):
* title = 'Hello World Example!'
* contents = 'Hello World!'
* t3 = Template3("sink")
*
* This should also detect cases of the following type :
*
* from Cheetah.Template import Template
* t3 = Template("sink")
*/
class CheetahTemplateInstantiationSink extends SSTISink {
override string toString() { result = "argument to Cheetah.Template.Template()" }
CheetahTemplateInstantiationSink() {
exists(CallNode call, ClassValue cv |
cv.getASuperType() = theCheetahTemplateClass() and
call.getFunction().pointsTo(cv) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,36 @@
/** Provides classes which model the `chevron` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the Value representing `chevron.render` function */
Value theChevronRenderFunc() { result = Value::named("chevron.render") }
/**
* Sink representing the `chevron.render` function call argument.
*
* import chevron
* tmp = chevron.render(`sink`,{ 'key' : 'value' })
*/
class ChevronRenderSink extends SSTISink {
override string toString() { result = "argument to chevron.render()" }
ChevronRenderSink() {
exists(CallNode call |
call.getFunction() = theChevronRenderFunc().getAReference() and
call.getArg(0) = this
)
// TODO: this should also detect :
// import chevron
// args = {
// 'template': 'sink',
// 'data': {
// 'mustache': 'World'
// }
// }
// chevron.render(**args)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,36 @@
/** Provides classes which model the `DjangoTemplate` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
ClassValue theDjangoTemplateClass() { result = Value::named("django.template.Template") }
/**
* Sink representng `django.template.Template` class instantiation argument.
*
* from django.template import Template
* template = Template(`sink`)
*/
class DjangoTemplateTemplateSink extends SSTISink {
override string toString() { result = "argument to Django.template()" }
DjangoTemplateTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theDjangoTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
// TODO
/**
* Sinks representng the django.template.Template class instantiation.
*
* from django.template import engines
*
* django_engine = engines["django"]
* template = django_engine.from_string(`sink`)
*/

View File

@@ -0,0 +1,26 @@
/** Provides classes which model templates in the`flask` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
Value theFlaskRenderTemplateClass() { result = Value::named("flask.render_template_string") }
/**
* Sink representng `flask.render_template_string` function call argument.
*
* from flask import render_template_string
* render_template_string(`sink`)
*/
class FlaskTemplateSink extends SSTISink {
override string toString() { result = "argument to flask.render_template_string()" }
FlaskTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theFlaskRenderTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,51 @@
/** Provides classes which model the `Genshi` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `Genshi.template.TextTemplate` */
ClassValue theGenshiTextTemplateClass() { result = Value::named("genshi.template.TextTemplate") }
/** returns the ClassValue representing `Genshi.template.MarkupTemplate` */
ClassValue theGenshiMarkupTemplateClass() {
result = Value::named("genshi.template.MarkupTemplate")
}
/**
* Sink representing the `genshi.template.TextTemplate` class instantiation argument.
*
* from genshi.template import TextTemplate
* tmpl = TextTemplate('sink')
*/
class GenshiTextTemplateSink extends SSTISink {
override string toString() { result = "argument to genshi.template.TextTemplate()" }
GenshiTextTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theGenshiTextTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* Sink representing the `genshi.template.MarkupTemplate` class instantiation argument.
*
* from genshi.template import MarkupTemplate
* tmpl = MarkupTemplate('sink')
*/
class GenshiMarkupTemplateSink extends SSTISink {
override string toString() { result = "argument to genshi.template.MarkupTemplate()" }
GenshiMarkupTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theGenshiMarkupTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,49 @@
/** Provides classes which model the `Jinja2` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `jinja2.Template` */
ClassValue theJinja2TemplateClass() { result = Value::named("jinja2.Template") }
/** returns the ClassValue representing `jinja2.Template` */
Value theJinja2FromStringValue() { result = Value::named("jinja2.from_string") }
/**
* Sink representing the `jinja2.Template` class instantiation argument.
*
* from jinja2 import Template
* template = Template(`sink`)
*/
class Jinja2TemplateSink extends SSTISink {
override string toString() { result = "argument to Jinja2.template()" }
Jinja2TemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theJinja2TemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/**
* Sink representing the `jinja2.Template` class instantiation argument.
*
* from jinja2 import Template
* template = Template(`sink`)
*/
class Jinja2FromStringSink extends SSTISink {
override string toString() { result = "argument to Jinja2.from_string()" }
Jinja2FromStringSink() {
exists(CallNode call |
call.getFunction().pointsTo(theJinja2FromStringValue()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,27 @@
/** Provides classes which model the `Mako` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `mako.template.Template` */
ClassValue theMakoTemplateClass() { result = Value::named("mako.template.Template") }
/**
* Sink representing the `mako.template.Template` class instantiation argument.
*
* from mako.template import Template
* mytemplate = Template("hello world!")
*/
class MakoTemplateSink extends SSTISink {
override string toString() { result = "argument to mako.template.Template()" }
MakoTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theMakoTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -0,0 +1,7 @@
import semmle.python.dataflow.TaintTracking
/**
* A generic taint sink that is vulnerable to template inclusions.
* The `temp` in `Jinja2.Template(temp)` and similar.
*/
abstract class SSTISink extends TaintSink { }

View File

@@ -0,0 +1,13 @@
/** Imports all files which model potential SSTI sinks */
import experimental.semmle.python.templates.Airspeed
import experimental.semmle.python.templates.Bottle
import experimental.semmle.python.templates.Chameleon
import experimental.semmle.python.templates.Cheetah
import experimental.semmle.python.templates.Chevron
import experimental.semmle.python.templates.DjangoTemplate
import experimental.semmle.python.templates.FlaskTemplate
import experimental.semmle.python.templates.Genshi
import experimental.semmle.python.templates.Jinja
import experimental.semmle.python.templates.Mako
import experimental.semmle.python.templates.TRender

View File

@@ -0,0 +1,27 @@
/** Provides classes which model the `TRender` package. */
import python
import semmle.python.web.HttpRequest
import experimental.semmle.python.templates.SSTISink
/** returns the ClassValue representing `trender.TRender` */
ClassValue theTRenderTemplateClass() { result = Value::named("trender.TRender") }
/**
* Sink representing the `trender.TRender` class instantiation argument.
*
* from trender import TRender
* template = TRender(`sink`)
*/
class TRenderTemplateSink extends SSTISink {
override string toString() { result = "argument to trender.TRender()" }
TRenderTemplateSink() {
exists(CallNode call |
call.getFunction().pointsTo(theTRenderTemplateClass()) and
call.getArg(0) = this
)
}
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}

View File

@@ -1,4 +1,5 @@
import python
import semmle.python.dataflow.TaintTracking
abstract class Template extends Module { }

View File

@@ -0,0 +1,14 @@
import airspeed
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
@route('/other')
def a():
template = request.args.get('template')
return airspeed.Template(template)

View File

@@ -0,0 +1,20 @@
from bottle import Bottle, route, request, redirect, response, SimpleTemplate
from bottle import template as temp
app = Bottle()
@route('/other')
def a():
template = request.query.template
tpl = SimpleTemplate(template)
tpl.render(name='World')
return tmp
@route('/other2')
def b():
template = request.query.template
temp(template, name='World')
return tmp

View File

@@ -0,0 +1,10 @@
from chameleon import PageTemplate
from django.urls import path
from django.http import HttpResponse
def chameleon(request):
template = request.GET['template']
tmpl = PageTemplate(template)
return HttpResponse(tmpl)

View File

@@ -0,0 +1,24 @@
from flask import Flask, request
import chevron
app = Flask(__name__)
@route('/other')
def a():
template = request.args.get('template')
return chevron.render(template, {"key": "value"})
@route('/other2')
def b():
template = request.args.get('template')
args = {
'template': template,
'data': {
'key': 'value'
}
}
return chevron.render(**args)

View File

@@ -0,0 +1,41 @@
from django.urls import path
from django.http import HttpResponse
from django.template import Template, Context, Engine, engines
def dj(request):
# Load the template
template = request.GET['template']
t = Template(template)
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
def djEngine(request):
# Load the template
template = request.GET['template']
django_engine = engines['django']
t = django_engine.from_string(template)
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
def djEngineJinja(request):
# Load the template
template = request.GET['template']
django_engine = engines['jinja']
t = django_engine.from_string(template)
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
urlpatterns = [
path('', dj),
path('', djEngine),
path('', djEngineJinja),
]

View File

@@ -0,0 +1,22 @@
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def home():
from flask import render_template_string
if request.args.get('template'):
return render_template_string(request.args.get('template'))
@app.route("/a")
def home():
import flask
return flask.render_template_string(request.args.get('template'))
if __name__ == "__main__":
app.run(debug=True)

View File

@@ -0,0 +1,18 @@
from django.urls import path
from django.http import HttpResponse
from genshi.template import TextTemplate,MarkupTemplate
def genshi1():
template = request.GET['template']
tmpl = MarkupTemplate(template)
return HttpResponse(tmpl)
def genshi2():
template = request.GET['template']
tmpl = TextTemplate(template)
return HttpResponse(tmpl)
urlpatterns = [
path('', genshi1),
path('', genshi2)
]

View File

@@ -0,0 +1,30 @@
from django.urls import path
from django.http import HttpResponse
from jinja2 import Template as Jinja2_Template
from jinja2 import Environment, DictLoader, escape
def j(request):
# Load the template
template = request.GET['template']
t = Jinja2_Template(template)
name = request.GET['name']
# Render the template with the context data
html = t.render(name=escape(name))
return HttpResponse(html)
def j2(request):
import jinja2
# Load the template
template = request.GET['template']
t = jinja2.from_string(template)
name = request.GET['name']
# Render the template with the context data
html = t.render(name=escape(name))
return HttpResponse(html)
urlpatterns = [
path('', jinja),
path('', jinja2)
]

View File

@@ -0,0 +1,15 @@
from django.urls import path
from django.http import HttpResponse
from mako.template import Template
def mako(request):
# Load the template
template = request.GET['template']
mytemplate = Template(template)
return HttpResponse(mytemplate)
urlpatterns = [
path('', mako)
]

View File

@@ -0,0 +1,13 @@
from django.urls import path
from django.http import HttpResponse
from trender import TRender
urlpatterns = [
path('', trender)
]
def trender(request):
template = request.GET['template']
compiled = TRender(template)
return HttpResponse(compiled])

View File

@@ -0,0 +1,33 @@
edges
| AirspeedSsti.py:13:16:13:27 | dict of externally controlled string | AirspeedSsti.py:13:16:13:43 | externally controlled string |
| AirspeedSsti.py:13:16:13:27 | dict of externally controlled string | AirspeedSsti.py:13:16:13:43 | externally controlled string |
| AirspeedSsti.py:13:16:13:43 | externally controlled string | AirspeedSsti.py:14:30:14:37 | externally controlled string |
| AirspeedSsti.py:13:16:13:43 | externally controlled string | AirspeedSsti.py:14:30:14:37 | externally controlled string |
| ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:10:16:10:43 | externally controlled string |
| ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:10:16:10:43 | externally controlled string |
| ChevronSsti.py:10:16:10:43 | externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string |
| ChevronSsti.py:10:16:10:43 | externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string |
| DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest |
| DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest |
| DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict |
| DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict |
| DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | DjangoTemplates.py:8:16:8:38 | externally controlled string |
| DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | DjangoTemplates.py:8:16:8:38 | externally controlled string |
| DjangoTemplates.py:8:16:8:38 | externally controlled string | DjangoTemplates.py:9:18:9:25 | externally controlled string |
| DjangoTemplates.py:8:16:8:38 | externally controlled string | DjangoTemplates.py:9:18:9:25 | externally controlled string |
| FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string |
| FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string |
| MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:8:16:8:22 | django.request.HttpRequest |
| MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:8:16:8:22 | django.request.HttpRequest |
| MakoSsti.py:8:16:8:22 | django.request.HttpRequest | MakoSsti.py:8:16:8:26 | django.http.request.QueryDict |
| MakoSsti.py:8:16:8:22 | django.request.HttpRequest | MakoSsti.py:8:16:8:26 | django.http.request.QueryDict |
| MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | MakoSsti.py:8:16:8:38 | externally controlled string |
| MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | MakoSsti.py:8:16:8:38 | externally controlled string |
| MakoSsti.py:8:16:8:38 | externally controlled string | MakoSsti.py:9:27:9:34 | externally controlled string |
| MakoSsti.py:8:16:8:38 | externally controlled string | MakoSsti.py:9:27:9:34 | externally controlled string |
#select
| AirspeedSsti.py:14:30:14:37 | template | AirspeedSsti.py:13:16:13:27 | dict of externally controlled string | AirspeedSsti.py:14:30:14:37 | externally controlled string | This Template depends on $@. | AirspeedSsti.py:13:16:13:27 | Attribute | a user-provided value |
| ChevronSsti.py:11:27:11:34 | template | ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | This Template depends on $@. | ChevronSsti.py:10:16:10:27 | Attribute | a user-provided value |
| DjangoTemplates.py:9:18:9:25 | template | DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:9:18:9:25 | externally controlled string | This Template depends on $@. | DjangoTemplates.py:6:8:6:14 | request | a user-provided value |
| FlaskTemplate.py:17:41:17:68 | Attribute() | FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | This Template depends on $@. | FlaskTemplate.py:17:41:17:52 | Attribute | a user-provided value |
| MakoSsti.py:9:27:9:34 | template | MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:9:27:9:34 | externally controlled string | This Template depends on $@. | MakoSsti.py:6:10:6:16 | request | a user-provided value |

View File

@@ -0,0 +1 @@
experimental/CWE-074/TemplateInjection.ql

View File

@@ -0,0 +1 @@
semmle-extractor-options: --max-import-depth=3 -p ../../query-tests/Security/lib/

View File

@@ -0,0 +1,10 @@
from bottle import Bottle, route, request, redirect, response
import airspeed
app = Bottle()
@route('/other')
def a():
return airspeed.Template("sink")

View File

@@ -0,0 +1 @@
| Airspeed.py:10:30:10:35 | argument to airspeed.Template() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Airspeed
from SSTISink s
select s

View File

@@ -0,0 +1,17 @@
from bottle import Bottle, route, request, redirect, response, SimpleTemplate
from bottle import template as temp
app = Bottle()
@route('/other')
def a():
template = "test"
tpl = SimpleTemplate(template)
@route('/other2')
def b():
template = "test"
return temp(template, name='World')

View File

@@ -0,0 +1,2 @@
| Bottle.py:11:26:11:33 | argument to bottle.SimpleTemplate() |
| Bottle.py:17:17:17:24 | argument to bottle.template() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Bottle
from SSTISink s
select s

View File

@@ -0,0 +1,5 @@
from chameleon import PageTemplate
def chameleon():
template = PageTemplate("sink")

View File

@@ -0,0 +1 @@
| Chameleon.py:5:29:5:34 | argument to Chameleon.PageTemplate() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Chameleon
from SSTISink s
select s

View File

@@ -0,0 +1,2 @@
| CheetahSinks.py:10:21:10:26 | argument to Cheetah.Template.Template() |
| CheetahSinks.py:20:20:20:25 | argument to Cheetah.Template.Template() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Cheetah
from SSTISink s
select s

View File

@@ -0,0 +1,20 @@
from bottle import Bottle, route, request, redirect, response, SimpleTemplate
from Cheetah.Template import Template
app = Bottle()
@route('/other')
def a():
return Template("sink")
class Template3(Template):
title = 'Hello World Example!'
contents = 'Hello World!'
@route('/other2')
def b():
t3 = Template3("sink")

View File

@@ -0,0 +1 @@
| ChevronSinks.py:10:27:10:32 | argument to chevron.render() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Chevron
from SSTISink s
select s

View File

@@ -0,0 +1,22 @@
from bottle import Bottle, route, request, redirect, response, SimpleTemplate
import chevron
app = Bottle()
@route('/other')
def a():
return chevron.render("sink", {"key": "value"})
@route('/other2')
def b():
sink = {
'template': "template",
'data': {
'key': 'value'
}
}
return chevron.render(**sink)

View File

@@ -0,0 +1 @@
| DjangoTemplates.py:9:18:9:25 | argument to Django.template() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.DjangoTemplate
from SSTISink s
select s

View File

@@ -0,0 +1,39 @@
from django.urls import path
from django.http import HttpResponse
from django.template import Template, Context, Engine, engines
def dj(request):
# Load the template
template = request.GET['template']
t = Template(template)
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
def djEngine(request):
# Load the template
template = request.GET['template']
django_engine = engines['django']
t = django_engine.from_string(template)
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
def djEngineJinja(request):
# Load the template
template = request.GET['template']
django_engine = engines['jinja']
t = django_engine.from_string(template)
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
urlpatterns = [
path('', dj)
]

View File

@@ -0,0 +1,10 @@
def genshi1():
from genshi.template import MarkupTemplate
tmpl = MarkupTemplate('sink')
def genshi2():
from genshi.template import TextTemplate
tmpl = TextTemplate('sink')

View File

@@ -0,0 +1,2 @@
| Genshi.py:5:27:5:32 | argument to genshi.template.MarkupTemplate() |
| Genshi.py:10:25:10:30 | argument to genshi.template.TextTemplate() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Genshi
from SSTISink s
select s

View File

@@ -0,0 +1,17 @@
from jinja2 import Template as Jinja2_Template
from jinja2 import Environment, DictLoader, escape
def jinja():
t = Jinja2_Template("sink")
def jinja2():
random = "esdad" + "asdad"
t = Jinja2_Template(random)
def jinja3():
random = 1234
t = Jinja2_Template("sink"+random)

View File

@@ -0,0 +1,3 @@
| Jinja2Templates.py:6:25:6:30 | argument to Jinja2.template() |
| Jinja2Templates.py:11:25:11:30 | argument to Jinja2.template() |
| Jinja2Templates.py:16:25:16:37 | argument to Jinja2.template() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Jinja
from SSTISink s
select s

View File

@@ -0,0 +1,5 @@
def mako():
from mako.template import Template
mytemplate = Template("sink")

View File

@@ -0,0 +1 @@
| Mako.py:5:27:5:32 | argument to mako.template.Template() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.Mako
from SSTISink s
select s

View File

@@ -0,0 +1,6 @@
def trender():
from trender import TRender
template = '@greet world!'
compiled = TRender(template)

View File

@@ -0,0 +1 @@
| TRender.py:6:24:6:31 | argument to trender.TRender() |

View File

@@ -0,0 +1,5 @@
import python
import experimental.semmle.python.templates.TRender
from SSTISink s
select s

View File

@@ -0,0 +1 @@
semmle-extractor-options: --lang=3 --max-import-depth=3 -p ../../../../../query-tests/Security/lib/

View File

@@ -0,0 +1,3 @@
class Template:
def __init__(self, content, filename="<string>"):
pass

View File

@@ -0,0 +1,2 @@
class Template(object):
pass

View File

@@ -0,0 +1,6 @@
def render(template='', data={}, partials_path='.', partials_ext='mustache',
partials_dict={}, padding='', def_ldel='{{', def_rdel='}}',
scopes=None):
pass

View File

@@ -28,3 +28,6 @@ def make_response(rv):
def escape(txt):
return Markup.escape(txt)
def render_template_string(source, **context):
pass

View File

@@ -18,3 +18,6 @@ class FileSystemLoader(object):
def __init__(self, searchpath):
pass
def from_string(source, globals=None, template_class=None):
pass