mirror of
https://github.com/github/codeql.git
synced 2025-12-23 12:16:33 +01:00
Refactor TemplateInjection libraries
This commit is contained in:
@@ -117,6 +117,7 @@ private module Frameworks {
|
||||
private import semmle.code.java.frameworks.Retrofit
|
||||
private import semmle.code.java.frameworks.Stream
|
||||
private import semmle.code.java.frameworks.Strings
|
||||
private import semmle.code.java.frameworks.Velocity
|
||||
private import semmle.code.java.frameworks.ratpack.Ratpack
|
||||
private import semmle.code.java.frameworks.ratpack.RatpackExec
|
||||
private import semmle.code.java.frameworks.spring.SpringCache
|
||||
@@ -141,6 +142,7 @@ private module Frameworks {
|
||||
private import semmle.code.java.security.LdapInjection
|
||||
private import semmle.code.java.security.MvelInjection
|
||||
private import semmle.code.java.security.OgnlInjection
|
||||
private import semmle.code.java.security.TemplateInjection
|
||||
private import semmle.code.java.security.XPath
|
||||
private import semmle.code.java.security.XsltInjection
|
||||
private import semmle.code.java.frameworks.Jdbc
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/** Definitions related to the FreeMarker Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `Template` class of the FreeMarker Template Engine */
|
||||
class TypeFreeMarkerTemplate extends Class {
|
||||
TypeFreeMarkerTemplate() { this.hasQualifiedName("freemarker.template", "Template") }
|
||||
}
|
||||
|
||||
/** The `process` method of the FreeMarker Template Engine's `Template` class */
|
||||
class MethodFreeMarkerTemplateProcess extends Method {
|
||||
MethodFreeMarkerTemplateProcess() {
|
||||
this.getDeclaringType() instanceof TypeFreeMarkerTemplate and
|
||||
this.hasName("process")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `StringTemplateLoader` class of the FreeMarker Template Engine */
|
||||
class TypeFreeMarkerStringLoader extends Class {
|
||||
TypeFreeMarkerStringLoader() { this.hasQualifiedName("freemarker.cache", "StringTemplateLoader") }
|
||||
}
|
||||
|
||||
/** The `process` method of the FreeMarker Template Engine's `StringTemplateLoader` class */
|
||||
class MethodFreeMarkerStringTemplateLoaderPutTemplate extends Method {
|
||||
MethodFreeMarkerStringTemplateLoaderPutTemplate() {
|
||||
this.getDeclaringType() instanceof TypeFreeMarkerStringLoader and
|
||||
this.hasName("putTemplate")
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/** Definitions related to the Jinjava Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `Jinjava` class of the Jinjava Templating Engine. */
|
||||
class TypeJinjava extends Class {
|
||||
TypeJinjava() { this.hasQualifiedName("com.hubspot.jinjava", "Jinjava") }
|
||||
}
|
||||
|
||||
/** The `render` method of the Jinjava Templating Engine. */
|
||||
class MethodJinjavaRender extends Method {
|
||||
MethodJinjavaRender() {
|
||||
this.getDeclaringType() instanceof TypeJinjava and
|
||||
this.hasName("render")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `render` method of the Jinjava Templating Engine. */
|
||||
class MethodJinjavaRenderForResult extends Method {
|
||||
MethodJinjavaRenderForResult() {
|
||||
this.getDeclaringType() instanceof TypeJinjava and
|
||||
this.hasName("renderForResult")
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/** Definitions related to the Pebble Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `PebbleEngine` class of the Pebble Templating Engine. */
|
||||
class TypePebbleEngine extends Class {
|
||||
TypePebbleEngine() { this.hasQualifiedName("com.mitchellbosecke.pebble", "PebbleEngine") }
|
||||
}
|
||||
|
||||
/** The `getTemplate` method of the Pebble Templating Engine. */
|
||||
class MethodPebbleGetTemplate extends Method {
|
||||
MethodPebbleGetTemplate() {
|
||||
this.getDeclaringType() instanceof TypePebbleEngine and
|
||||
this.hasName(["getTemplate", "getLiteralTemplate"])
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/** Definitions related to the Thymeleaf Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/**
|
||||
* A class implementing the `ITemplateEngine` interface of the Thymeleaf
|
||||
* Templating Engine such as the `TemplateEngine` class.
|
||||
*/
|
||||
class TypeThymeleafTemplateEngine extends Class {
|
||||
TypeThymeleafTemplateEngine() {
|
||||
this.hasQualifiedName("org.thymeleaf", "TemplateEngine")
|
||||
or
|
||||
exists(Type t | this.getASupertype*().extendsOrImplements(t) |
|
||||
t.hasName("org.thymeleaf.ITemplateEngine")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `process` or `processThrottled` method of the Thymeleaf Templating Engine. */
|
||||
class MethodThymeleafProcess extends Method {
|
||||
MethodThymeleafProcess() {
|
||||
this.getDeclaringType() instanceof TypeThymeleafTemplateEngine and
|
||||
this.hasName(["process", "processThrottled"])
|
||||
}
|
||||
}
|
||||
@@ -1,119 +1,14 @@
|
||||
/** Definitions related to the Apache Velocity Templating library. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/** The `org.apache.velocity.context.AbstractContext` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityAbstractContext extends Class {
|
||||
TypeVelocityAbstractContext() {
|
||||
this.hasQualifiedName("org.apache.velocity.context", "AbstractContext")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.runtime.RuntimeServices` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityRuntimeRuntimeServices extends Class {
|
||||
TypeVelocityRuntimeRuntimeServices() {
|
||||
this.hasQualifiedName("org.apache.velocity.runtime", "RuntimeServices")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.Template` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityTemplate extends Class {
|
||||
TypeVelocityTemplate() { this.hasQualifiedName("org.apache.velocity", "Template") }
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.runtime.RuntimeSingleton` classTemplating Engine. */
|
||||
class TypeVelocityRuntimeRuntimeSingleton extends Class {
|
||||
TypeVelocityRuntimeRuntimeSingleton() {
|
||||
this.hasQualifiedName("org.apache.velocity.runtime", "RuntimeSingleton")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.VelocityEngine` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityVelocityEngine extends Class {
|
||||
TypeVelocityVelocityEngine() { this.hasQualifiedName("org.apache.velocity", "VelocityEngine") }
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.app.VelocityEngine` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityAppVelocityEngine extends RefType {
|
||||
TypeVelocityAppVelocityEngine() {
|
||||
this.hasQualifiedName("org.apache.velocity.app", "VelocityEngine")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.app.Velocity` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityAppVelocity extends RefType {
|
||||
TypeVelocityAppVelocity() { this.hasQualifiedName("org.apache.velocity.app", "Velocity") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `org.apache.velocity.runtime.resource.util.StringResourceRepository` interface
|
||||
* of the Velocity Templating Engine.
|
||||
*/
|
||||
class TypeVelocityStringResourceRepo extends RefType {
|
||||
TypeVelocityStringResourceRepo() {
|
||||
this.hasQualifiedName("org.apache.velocity.runtime.resource.util", "StringResourceRepository")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `internalPut` and `put` methods of the Velocity Templating Engine. */
|
||||
class MethodVelocityContextPut extends Method {
|
||||
MethodVelocityContextPut() {
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityAbstractContext and
|
||||
this.hasName(["put", "internalPut"])
|
||||
}
|
||||
}
|
||||
|
||||
/** The `evaluate` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityEvaluate extends Method {
|
||||
MethodVelocityEvaluate() {
|
||||
// static boolean evaluate(Context context, Writer out, String logTag, String instring)
|
||||
// static boolean evaluate(Context context, Writer writer, String logTag, Reader reader)
|
||||
(
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocity or
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocityEngine or
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityRuntimeRuntimeServices
|
||||
) and
|
||||
this.hasName("evaluate")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `mergeTemplate` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityMergeTemplate extends Method {
|
||||
MethodVelocityMergeTemplate() {
|
||||
// static boolean mergeTemplate(String templateName, String encoding, Context context, Writer writer)
|
||||
(
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocity or
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocityEngine
|
||||
) and
|
||||
this.hasName("mergeTemplate")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `merge` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityMerge extends Method {
|
||||
MethodVelocityMerge() {
|
||||
// void merge(Context context, Writer writer)
|
||||
// void merge(Context context, Writer writer, List<String> macroLibraries)
|
||||
this.getDeclaringType() instanceof TypeVelocityTemplate and
|
||||
this.hasName("merge")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `parse` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityParse extends Method {
|
||||
MethodVelocityParse() {
|
||||
(
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityRuntimeRuntimeSingleton or
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityRuntimeRuntimeServices
|
||||
) and
|
||||
this.hasName("parse")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `putStringResource` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityPutStringResource extends Method {
|
||||
MethodVelocityPutStringResource() {
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityStringResourceRepo and
|
||||
this.hasName("putStringResource")
|
||||
private class VelocitySummaryModels extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"org.apache.velocity.context;AbstractContext;true;put;;;Argument[1];Argument[-1];taint;manual",
|
||||
"org.apache.velocity.context;AbstractContext;true;internalPut;;;Argument[1];Argument[-1];taint;manual",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
106
java/ql/lib/semmle/code/java/security/TemplateInjection.qll
Normal file
106
java/ql/lib/semmle/code/java/security/TemplateInjection.qll
Normal file
@@ -0,0 +1,106 @@
|
||||
/** Definitions related to the server-side template injection (SST) query. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
|
||||
/**
|
||||
* A source for server-side template injection (SST) vulnerabilities.
|
||||
*/
|
||||
abstract class TemplateInjectionSource extends DataFlow::Node {
|
||||
/** Holds if this source has the specified `state`. */
|
||||
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink for server-side template injection (SST) vulnerabilities.
|
||||
*/
|
||||
abstract class TemplateInjectionSink extends DataFlow::Node {
|
||||
/** Holds if this sink has the specified `state`. */
|
||||
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit class for adding additional taint steps.
|
||||
*
|
||||
* Extend this class to add additional taint steps that should apply to flows related to
|
||||
* server-side template injection (SST) vulnerabilities.
|
||||
*/
|
||||
class TemplateInjectionAdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if the step from `node1` to `node2` should be considered a taint
|
||||
* step for flows related to server-side template injection (SST) vulnerabilities.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
/**
|
||||
* Holds if the step from `node1` to `node2` should be considered a taint
|
||||
* step for flows related toserver-side template injection (SST) vulnerabilities.
|
||||
* This step is only applicable in `state1` and updates the flow state to `state2`.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(
|
||||
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
|
||||
DataFlow::FlowState state2
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sanitizer for server-side template injection (SST) vulnerabilities.
|
||||
*/
|
||||
abstract class TemplateInjectionSanitizer extends DataFlow::Node {
|
||||
/** Holds if this sanitizer has the specified `state`. */
|
||||
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
|
||||
}
|
||||
|
||||
private class DefaultTemplateInjectionSource extends TemplateInjectionSource instanceof RemoteFlowSource {
|
||||
}
|
||||
|
||||
private class DefaultTemplateInjectionSink extends TemplateInjectionSink {
|
||||
DefaultTemplateInjectionSink() { sinkNode(this, "ssti") }
|
||||
}
|
||||
|
||||
private class DefaultTemplateInjectionSanitizer extends TemplateInjectionSanitizer {
|
||||
DefaultTemplateInjectionSanitizer() {
|
||||
this.getType() instanceof PrimitiveType or
|
||||
this.getType() instanceof BoxedType or
|
||||
this.getType() instanceof NumericType
|
||||
}
|
||||
}
|
||||
|
||||
private class TemplateInjectionSinkModels extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"freemarker.template;Template;true;process;;;Argument[0];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,Reader);;Argument[1];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,Reader,Configuration);;Argument[1];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,Reader,Configuration,String);;Argument[1];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,String,Reader,Configuration);;Argument[2];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,String,Reader,Configuration,String);;Argument[2];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,String,Reader,Configuration,ParserConfiguration,String);;Argument[2];ssti;manual",
|
||||
"freemarker.template;Template;true;Template;(String,String,Configuration);;Argument[1];ssti;manual",
|
||||
"freemarker.cache;StringTemplateLoader;true;putTemplate;;;Argument[1];ssti;manual",
|
||||
"com.mitchellbosecke.pebble;PebbleEngine;true;getTemplate;;;Argument[0];ssti;manual",
|
||||
"com.mitchellbosecke.pebble;PebbleEngine;true;getLiteralTemplate;;;Argument[0];ssti;manual",
|
||||
"com.hubspot.jinjava;Jinjava;true;renderForResult;;;Argument[0];ssti;manual",
|
||||
"com.hubspot.jinjava;Jinjava;true;render;;;Argument[0];ssti;manual",
|
||||
"org.thymeleaf;ITemplateEngine;true;process;;;Argument[0];ssti;manual",
|
||||
"org.thymeleaf;ITemplateEngine;true;processThrottled;;;Argument[0];ssti;manual",
|
||||
"org.apache.velocity.app;Velocity;true;evaluate;;;Argument[0];ssti;manual",
|
||||
"org.apache.velocity.app;Velocity;true;evaluate;;;Argument[3];ssti;manual",
|
||||
"org.apache.velocity,app;VelocityEngine;true;evaluate;;;Argument[0];ssti;manual",
|
||||
"org.apache.velocity,app;VelocityEngine;true;evaluate;;;Argument[3];ssti;manual",
|
||||
"org.apache.velocity.app;Velocity;true;mergeTemplate;;;Argument[2];ssti;manual",
|
||||
"org.apache.velocity.app;VelocityEngine;true;mergeTemplate;;;Argument[2];ssti;manual",
|
||||
"org.apache.velocity.runtime.resource.util;StringResourceRepository;true;putStringResource;;;Argument[1];ssti;manual",
|
||||
"org.apache.velocity.runtime;RuntimeServices;true;evaluate;;;Argument[0];ssti;manual",
|
||||
"org.apache.velocity.runtime;RuntimeServices;true;evaluate;;;Argument[3];ssti;manual",
|
||||
"org.apache.velocity.runtime;RuntimeServices;true;parse;;;Argument[0];ssti;manual",
|
||||
"org.apache.velocity.runtime;RuntimeSingleton;true;parse;;;Argument[0];ssti;manual",
|
||||
"org.apache.velocity;Template;true;merge;;;Argument[0];ssti;manual"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/** Provides a taint tracking configuration for server-side template injection (SST) vulnerabilities */
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.TemplateInjection
|
||||
|
||||
/** A taint tracking configuration to reason about server-side template injection (SST) vulnerabilities */
|
||||
class TemplateInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
TemplateInjectionFlowConfig() { this = "TemplateInjectionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { this.isSource(source, _) }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
|
||||
source.(TemplateInjectionSource).hasState(state)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
|
||||
sink.(TemplateInjectionSink).hasState(state)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) { this.isSanitizer(sanitizer, _) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer, DataFlow::FlowState state) {
|
||||
sanitizer.(TemplateInjectionSanitizer).hasState(state)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, node2)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(
|
||||
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
|
||||
DataFlow::FlowState state2
|
||||
) {
|
||||
any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, state1, node2, state2)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @name Server Side Template Injection
|
||||
* @name Server-side template injection
|
||||
* @description Untrusted input used as a template parameter can lead to remote code execution.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
import TemplateInjection
|
||||
import semmle.code.java.security.TemplateInjectionQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from TemplateInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
/** Definitions related to the Server Side Template Injection (SSTI) query. */
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.FreeMarker
|
||||
import semmle.code.java.frameworks.Velocity
|
||||
import semmle.code.java.frameworks.JinJava
|
||||
import semmle.code.java.frameworks.Pebble
|
||||
import semmle.code.java.frameworks.Thymeleaf
|
||||
|
||||
/** A taint tracking configuration to reason about Server Side Template Injection (SSTI) vulnerabilities */
|
||||
class TemplateInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
TemplateInjectionFlowConfig() { this = "TemplateInjectionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ) {
|
||||
exists(AdditionalFlowStep a | a.isAdditionalTaintStep(prev, succ))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink for Server Side Template Injection (SSTI) vulnerabilities
|
||||
*/
|
||||
abstract private class Sink extends DataFlow::ExprNode { }
|
||||
|
||||
/**
|
||||
* A data flow step for Server Side Template Injection (SSTI) vulnerabilities
|
||||
*/
|
||||
private class AdditionalFlowStep extends Unit {
|
||||
abstract predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to FreeMarker template engine's `process` method call.
|
||||
*/
|
||||
private class FreeMarkerProcessSink extends Sink {
|
||||
FreeMarkerProcessSink() {
|
||||
exists(MethodAccess m |
|
||||
m.getCallee() instanceof MethodFreeMarkerTemplateProcess and
|
||||
m.getArgument(0) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An reader passed an argument to FreeMarker template engine's `Template`
|
||||
* construtor call.
|
||||
*/
|
||||
private class FreeMarkerConstructorSink extends Sink {
|
||||
FreeMarkerConstructorSink() {
|
||||
// Template(java.lang.String name, java.io.Reader reader)
|
||||
// Template(java.lang.String name, java.io.Reader reader, Configuration cfg)
|
||||
// Template(java.lang.String name, java.io.Reader reader, Configuration cfg, java.lang.String encoding)
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader reader, Configuration cfg)
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader reader, Configuration cfg, ParserConfiguration customParserConfiguration, java.lang.String encoding)
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader reader, Configuration cfg, java.lang.String encoding)
|
||||
exists(ConstructorCall cc, Expr e |
|
||||
cc.getConstructor().getDeclaringType() instanceof TypeFreeMarkerTemplate and
|
||||
e = cc.getAnArgument() and
|
||||
(
|
||||
e.getType().(RefType).hasQualifiedName("java.io", "Reader") and
|
||||
this.asExpr() = e
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructor().getDeclaringType() instanceof TypeFreeMarkerTemplate and
|
||||
// Template(java.lang.String name, java.lang.String sourceCode, Configuration cfg)
|
||||
cc.getNumArgument() = 3 and
|
||||
cc.getArgument(1).getType() instanceof TypeString and
|
||||
this.asExpr() = cc.getArgument(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to FreeMarker template engine's `putTemplate` method call.
|
||||
*/
|
||||
private class FreeMarkerStringTemplateLoaderPutTemplateSink extends Sink {
|
||||
FreeMarkerStringTemplateLoaderPutTemplateSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(1) and
|
||||
ma.getMethod() instanceof MethodFreeMarkerStringTemplateLoaderPutTemplate
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Pebble template engine's `getLiteralTemplate` or `getTemplate` method call.
|
||||
*/
|
||||
private class PebbleGetTemplateSinkTemplateSink extends Sink {
|
||||
PebbleGetTemplateSinkTemplateSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
ma.getMethod() instanceof MethodPebbleGetTemplate
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to JinJava template engine's `render` or `renderForResult` method call.
|
||||
*/
|
||||
private class JinjavaRenderSink extends Sink {
|
||||
JinjavaRenderSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
(
|
||||
ma.getMethod() instanceof MethodJinjavaRenderForResult
|
||||
or
|
||||
ma.getMethod() instanceof MethodJinjavaRender
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to ThymeLeaf template engine's `process` method call.
|
||||
*/
|
||||
private class ThymeLeafRenderSink extends Sink {
|
||||
ThymeLeafRenderSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
ma.getMethod() instanceof MethodThymeleafProcess
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tainted data flowing into a Velocity Context through `put` method taints the context.
|
||||
*/
|
||||
private class VelocityContextFlow extends AdditionalFlowStep {
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ) {
|
||||
exists(MethodAccess m | m.getMethod() instanceof MethodVelocityContextPut |
|
||||
m.getArgument(1) = prev.asExpr() and
|
||||
succ.asExpr() = m.getQualifier()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `mergeTemplate` method call.
|
||||
*/
|
||||
private class VelocityMergeTempSink extends Sink {
|
||||
VelocityMergeTempSink() {
|
||||
exists(MethodAccess m |
|
||||
// static boolean mergeTemplate(String templateName, String encoding, Context context, Writer writer)
|
||||
m.getCallee() instanceof MethodVelocityMergeTemplate and
|
||||
m.getArgument(2) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `mergeTemplate` method call.
|
||||
*/
|
||||
private class VelocityMergeSink extends Sink {
|
||||
VelocityMergeSink() {
|
||||
exists(MethodAccess m |
|
||||
m.getCallee() instanceof MethodVelocityMerge and
|
||||
// public void merge(Context context, Writer writer)
|
||||
// public void merge(Context context, Writer writer, List<String> macroLibraries)
|
||||
m.getArgument(0) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `evaluate` method call.
|
||||
*/
|
||||
private class VelocityEvaluateSink extends Sink {
|
||||
VelocityEvaluateSink() {
|
||||
exists(MethodAccess m |
|
||||
m.getCallee() instanceof MethodVelocityEvaluate and
|
||||
m.getArgument([0, 3]) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `parse` method call.
|
||||
*/
|
||||
private class VelocityParseSink extends Sink {
|
||||
VelocityParseSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
ma.getMethod() instanceof MethodVelocityParse
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `putStringResource` method call.
|
||||
*/
|
||||
private class VelocityPutStringResSink extends Sink {
|
||||
VelocityPutStringResSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(1) and
|
||||
ma.getMethod() instanceof MethodVelocityPutStringResource
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user