Copy template injection to standard pack + add jinja sinks

This commit is contained in:
Joe Farebrother
2024-11-05 17:06:53 +00:00
parent 1266b244f5
commit 8647073433
6 changed files with 106 additions and 3 deletions

View File

@@ -861,6 +861,32 @@ class LdapFilterEscaping extends Escaping {
LdapFilterEscaping() { super.getKind() = Escaping::getLdapFilterKind() }
}
/**
* A data-flow node that constructs a template in a templating engine.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `TemplateConstruction::Range` instead.
*/
class TemplateConstruction extends DataFlow::Node instanceof TemplateConstruction::Range {
/** Gets the argument that specifies the template source. */
DataFlow::Node getSourceArg() { result = super.getSourceArg() }
}
/** Provides classes for modelling template construction APIs. */
module TemplateConstruction {
/**
* A data-flow node that constructs a template in a templating engine.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `TemplateConstruction` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the argument that specifies the template source. */
abstract DataFlow::Node getSourceArg();
}
}
/** Provides classes for modeling HTTP-related APIs. */
module Http {
/** Gets an HTTP verb, in upper case */

View File

@@ -0,0 +1,50 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "template injection"
* vulnerabilities, as well as extension points for adding your own.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.dataflow.new.BarrierGuards
/**
* Provides default sources, sinks and sanitizers for detecting
* "template injection"
* vulnerabilities, as well as extension points for adding your own.
*/
module TemplateInjection {
/**
* A data flow source for "template injection" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "template injection" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for "template injection" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* An active threat-model source, considered as a flow source.
*/
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }
/**
* A SQL statement of a SQL construction, considered as a flow sink.
*/
class TemplateConstructionAsSink extends Sink {
TemplateConstructionAsSink() { this = any(TemplateConstruction c).getSourceArg() }
}
/**
* A comparison with a constant, considered as a sanitizer-guard.
*/
class ConstCompareAsSanitizerGuard extends Sanitizer, ConstCompareBarrier { }
}

View File

@@ -0,0 +1,22 @@
/**
* Provides a taint-tracking configuration for detecting "template injection" vulnerabilities.
*
* Note, for performance reasons: only import this file if
* `TemplateInjectionFlow` is needed, otherwise
* `TemplateInjectionCustomizations` should be imported instead.
*/
private import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import TemplateInjectionCustomizations::TemplateInjection
module TemplateInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof Source }
predicate isSink(DataFlow::Node node) { node instanceof Sink }
predicate isBarrierIn(DataFlow::Node node) { node instanceof Sanitizer }
}
module TemplateInjectionFlow = TaintTracking::Global<TemplateInjectionConfig>;

View File

@@ -134,7 +134,12 @@ class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallN
/** A call to `jinja2.from_string`. */
class Jinja2FromStringConstruction extends TemplateConstruction::Range, API::CallNode {
Jinja2FromStringConstruction() {
this = API::moduleImport("jinja2").getMember("from_string").getACall()
this =
API::moduleImport("jinja2")
.getMember("Environment")
.getReturn()
.getMember("from_string")
.getACall()
}
override DataFlow::Node getSourceArg() { result = this.getArg(0) }

View File

@@ -6,7 +6,7 @@
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.Concepts as C
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.dataflow.new.BarrierGuards
private import TemplateConstructionConcept
@@ -40,7 +40,7 @@ module TemplateInjection {
/**
* An active threat-model source, considered as a flow source.
*/
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }
private class ActiveThreatModelSourceAsSource extends Source, C::ActiveThreatModelSource { }
/**
* A SQL statement of a SQL construction, considered as a flow sink.