diff --git a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql index 1ab93ae4a2b..820937f8649 100644 --- a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql +++ b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql @@ -12,6 +12,8 @@ */ import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.ApiGraphs /* * Jinja 2 Docs: @@ -25,25 +27,24 @@ import python * safe1_tmpl = Template('Hello {{ name }}!', autoescape=True) */ -ClassValue jinja2EnvironmentOrTemplate() { - result = Value::named("jinja2.Environment") +private API::Node jinja2EnvironmentOrTemplate() { + result = API::moduleImport("jinja2").getMember("Environment") or - result = Value::named("jinja2.Template") + result = API::moduleImport("jinja2").getMember("Template") } -ControlFlowNode getAutoEscapeParameter(CallNode call) { result = call.getArgByName("autoescape") } - -from CallNode call +from API::CallNode call where - call.getFunction().pointsTo(jinja2EnvironmentOrTemplate()) and - not exists(call.getNode().getStarargs()) and - not exists(call.getNode().getKwargs()) and + call = jinja2EnvironmentOrTemplate().getACall() and + not exists(call.asCfgNode().(CallNode).getNode().getStarargs()) and + not exists(call.asCfgNode().(CallNode).getNode().getKwargs()) and ( - not exists(getAutoEscapeParameter(call)) + not exists(call.getArgByName("autoescape")) or - exists(Value isFalse | - getAutoEscapeParameter(call).pointsTo(isFalse) and - isFalse.getDefiniteBooleanValue() = false - ) + call.getKeywordParameter("autoescape") + .getAValueReachingRhs() + .asExpr() + .(ImmutableLiteral) + .booleanValue() = false ) select call, "Using jinja2 templates with autoescape=False can potentially allow XSS attacks." diff --git a/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.expected b/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.expected index 1813aa1a50d..918fbdf604d 100644 --- a/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.expected +++ b/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.expected @@ -2,4 +2,5 @@ | jinja2_escaping.py:41:5:41:29 | ControlFlowNode for Environment() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. | | jinja2_escaping.py:43:1:43:3 | ControlFlowNode for E() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. | | jinja2_escaping.py:44:1:44:15 | ControlFlowNode for E() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. | +| jinja2_escaping.py:50:13:50:40 | ControlFlowNode for Environment() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. | | jinja2_escaping.py:53:15:53:43 | ControlFlowNode for Template() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. |