Add concepts tests + some fixes

This commit is contained in:
Joe Farebrother
2024-11-21 14:56:44 +00:00
parent 1cb01a286d
commit cea196ec61
29 changed files with 133 additions and 8 deletions

View File

@@ -722,10 +722,13 @@ module Flask {
}
}
/** A call to `flask.render_template_string` as a template construction sink. */
/** A call to `flask.render_template_string` or `flask.stream_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()
this =
API::moduleImport("flask")
.getMember(["render_template_string", "stream_template_string"])
.getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }

View File

@@ -21,7 +21,7 @@ module Genshi {
API::moduleImport("genshi")
.getMember("template")
.getMember("text")
.getMember(["NewTextTemplate", "OldTextTemplate"])
.getMember(["NewTextTemplate", "OldTextTemplate", "TextTemplate"])
.getACall()
}

View File

@@ -24,6 +24,7 @@ module Jinja2 {
override DataFlow::Node getSourceArg() { result = this.getArg(0) }
}
/** Definitions for modeling jinja `Environment`s. */
module EnvironmentClass {
/** Gets a reference to the `jinja2.Environment` class. */
API::Node classRef() {

View File

@@ -663,6 +663,20 @@ module CorsMiddlewareTest implements TestSig {
}
}
module TemplateConstructionTest implements TestSig {
string getARelevantTag() { result = "templateConstruction" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(TemplateConstruction tc |
location = tc.getLocation() and
element = tc.toString() and
value = prettyNodeForInlineTest(tc.getSourceArg()) and
tag = "templateConstruction"
)
}
}
import MakeTest<MergeTests5<MergeTests5<SystemCommandExecutionTest, DecodingTest, EncodingTest, LoggingTest,
CodeExecutionTest>,
MergeTests5<SqlConstructionTest, SqlExecutionTest, XPathConstructionTest, XPathExecutionTest,
@@ -673,4 +687,5 @@ import MakeTest<MergeTests5<MergeTests5<SystemCommandExecutionTest, DecodingTest
MergeTests5<FileSystemAccessTest, FileSystemWriteAccessTest, PathNormalizationTest,
SafeAccessCheckTest, PublicKeyGenerationTest>,
MergeTests5<CryptographicOperationTest, HttpClientRequestTest, CsrfProtectionSettingTest,
CsrfLocalProtectionSettingTest, MergeTests<XmlParsingTest, ThreatModelSourceTest>>>>
CsrfLocalProtectionSettingTest,
MergeTests3<XmlParsingTest, ThreatModelSourceTest, TemplateConstructionTest>>>>

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,9 @@
from genshi.template.text import TextTemplate, NewTextTemplate, OldTextTemplate
from genshi.template.markup import MarkupTemplate
def test():
a = TextTemplate("abc") # $ templateConstruction="abc"
a = OldTextTemplate("abc") # $ templateConstruction="abc"
a = NewTextTemplate("abc") # $ templateConstruction="abc"
a = MarkupTemplate("abc") # $ templateConstruction="abc"
return a

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
from mako.template import Template
def test():
return Template("abc") # $ templateConstruction="abc"

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
from trender import TRender
def test():
return TRender("abc") # $ templateConstruction="abc"

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
from airspeed import Template
def test():
return Template("abc") # $ templateConstruction="abc"

View File

@@ -0,0 +1,9 @@
import bottle
from bottle import response, request, template, SimpleTemplate
app = bottle.app()
@app.route('/test', method=['OPTIONS', 'GET']) # $ routeSetup="/test"
def test1(): # $ requestHandler
template("abc") # $ templateConstruction="abc"
SimpleTemplate("abc") # $ templateConstruction="abc"
return '[1]' # $ HttpResponse mimetype=text/html responseBody='[1]'

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
from chameleon import PageTemplate
def test():
return PageTemplate("abc") # $ templateConstruction="abc"

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
from chevron import render
def test():
return render("abc") # $ templateConstruction="abc"

View File

@@ -0,0 +1,17 @@
from django.template import Template, engines
from django.urls import path
from django.http.response import HttpResponse,
def a(request): # $requestHandler
t = Template("abc").render() # $templateConstruction="abc"
return HttpResponse(t) # $HttpResponse
def b(request): # $requestHandler
# This case is not yet supported
t = django.template.engines["django"].from_string("abc") # $MISSING:templateConstruction="abc"
return HttpResponse(t) # $HttpResponse
urlpatterns = [
path("a", a), # $ routeSetup="a"
path("b", b), # $ routeSetup="b"
]

View File

@@ -222,25 +222,25 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route
# render_template_string
source = TAINTED_STRING
ensure_tainted(source) # $ tainted
res = render_template_string(source)
res = render_template_string(source) # $ templateConstruction=source
ensure_tainted(res) # $ tainted
# since template variables are auto-escaped, we don't treat result as tainted
# see https://flask.palletsprojects.com/en/2.3.x/api/#flask.render_template_string
res = render_template_string("Hello {{ foo }}", foo=TAINTED_STRING)
res = render_template_string("Hello {{ foo }}", foo=TAINTED_STRING) # $ templateConstruction="Hello {{ foo }}"
ensure_not_tainted(res)
# stream_template_string
source = TAINTED_STRING
ensure_tainted(source) # $ tainted
res = stream_template_string(source)
res = stream_template_string(source) # $ templateConstruction=source
for x in res:
ensure_tainted(x) # $ tainted
# since template variables are auto-escaped, we don't treat result as tainted
# see https://flask.palletsprojects.com/en/2.3.x/api/#flask.stream_template_string
res = stream_template_string("Hello {{ foo }}", foo=TAINTED_STRING)
res = stream_template_string("Hello {{ foo }}", foo=TAINTED_STRING) # $ templateConstruction="Hello {{ foo }}"
for x in res:
ensure_not_tainted(x)

View File

@@ -0,0 +1,16 @@
from flask import Flask, Response, stream_with_context, render_template_string, stream_template_string
app = Flask(__name__)
@app.route("/a") # $routeSetup="/a"
def a(): # $requestHandler
r = render_template_string("abc") # $ templateConstruction="abc"
return r # $ HttpResponse
@app.route("/b") # $routeSetup="/b"
def b(): # $requestHandler
s = stream_template_string("abc") # $ templateConstruction="abc"
r = Response(stream_with_context(s)) # $ HttpResponse
return r # $ HttpResponse
if __name__ == "__main__":
app.run(debug=True)

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,7 @@
from jinja2 import Environment, Template
def test():
env = Environment()
t = env.from_string("abc") # $ templateConstruction="abc"
t = Template("abc") # $ templateConstruction="abc"
return t