[pitboss] phase 04: Track J.2 + Track L.2 — SSTI corpus + Jinja2 / ERB / Twig / Thymeleaf / Handlebars adapters

This commit is contained in:
pitboss 2026-05-17 18:51:13 -05:00
parent b5e6dddf2c
commit 8583b29796
34 changed files with 1868 additions and 29 deletions

View file

@ -0,0 +1,16 @@
// Phase 04 (Track J.2) Java Thymeleaf benign control fixture.
//
// Renders a fixed template that interpolates the body as a model
// variable; the user-controlled value never reaches the template
// compiler.
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
public class Benign {
public static String run(String body) {
TemplateEngine engine = new TemplateEngine();
Context ctx = new Context();
ctx.setVariable("safeBody", body);
return engine.process("[[${safeBody}]]", ctx);
}
}

View file

@ -0,0 +1,14 @@
// Phase 04 (Track J.2) Java Thymeleaf SSTI vuln fixture.
//
// The body reaches TemplateEngine.process directly, so an attacker
// who controls the body can render arbitrary Thymeleaf expressions.
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
public class Vuln {
public static String run(String body) {
TemplateEngine engine = new TemplateEngine();
Context ctx = new Context();
return engine.process(body, ctx);
}
}

View file

@ -0,0 +1,14 @@
// Phase 04 (Track J.2) — JavaScript Handlebars benign control fixture.
//
// Renders a fixed template that interpolates the body as a context
// variable; the user-controlled value never reaches the template
// compiler.
const Handlebars = require('handlebars');
const template = Handlebars.compile('{{safeBody}}');
function run(body) {
return template({ safeBody: body });
}
module.exports = { run };

View file

@ -0,0 +1,17 @@
// Phase 04 (Track J.2) — JavaScript Handlebars SSTI vuln fixture.
//
// The body is handed straight to Handlebars.compile so an attacker
// who controls the body reaches the template compiler and can render
// arbitrary helper calls.
const Handlebars = require('handlebars');
Handlebars.registerHelper('multiply', function (a, b) {
return Number(a) * Number(b);
});
function run(body) {
const template = Handlebars.compile(body);
return template({});
}
module.exports = { run };

View file

@ -0,0 +1,14 @@
<?php
// Phase 04 (Track J.2) — PHP Twig benign control fixture.
//
// Renders a fixed template that interpolates the user value as a
// variable; the body never reaches the template compiler.
use Twig\Environment;
use Twig\Loader\ArrayLoader;
function run(string $body): string {
$twig = new Environment(new ArrayLoader([
'page' => '{{ safe_body }}',
]));
return $twig->render('page', ['safe_body' => $body]);
}

View file

@ -0,0 +1,14 @@
<?php
// Phase 04 (Track J.2) — PHP Twig SSTI vuln fixture.
//
// The body is handed straight to Twig\Environment::createTemplate so
// an attacker who controls the body reaches Twig's expression
// evaluator and can render arbitrary expressions.
use Twig\Environment;
use Twig\Loader\ArrayLoader;
function run(string $body): string {
$twig = new Environment(new ArrayLoader([]));
$template = $twig->createTemplate($body);
return $template->render([]);
}

View file

@ -0,0 +1,13 @@
"""Phase 04 (Track J.2) — Python Jinja2 benign control fixture.
The function escapes the body as plain text before handing it to a
fixed Jinja2 template that never interpolates the user-controlled
value, so even an SSTI-shaped payload cannot reach the evaluator.
"""
from jinja2 import Template
def run(body: str) -> str:
safe = body.replace("{", "&#123;").replace("}", "&#125;")
template = Template("{{ safe_body | safe }}")
return template.render(safe_body=safe)

View file

@ -0,0 +1,13 @@
"""Phase 04 (Track J.2) — Python Jinja2 SSTI vuln fixture.
The function pulls a template body off the request and pipes it
straight into `jinja2.Template(...).render()` without sandboxing or
expression filtering, so an attacker who controls the body reaches the
expression evaluator and can render arbitrary expressions.
"""
from jinja2 import Template
def run(body: str) -> str:
template = Template(body)
return template.render()

View file

@ -0,0 +1,11 @@
# Phase 04 (Track J.2) — Ruby ERB benign control fixture.
#
# Escapes ERB markers in the body before rendering through a fixed
# template that interpolates only the sanitised value, so SSTI-shaped
# input cannot reach the evaluator.
require 'erb'
def run(body)
safe_body = body.gsub(/<%/, '&lt;%').gsub(/%>/, '%&gt;')
ERB.new('<%= safe_body %>').result(binding)
end

View file

@ -0,0 +1,9 @@
# Phase 04 (Track J.2) — Ruby ERB SSTI vuln fixture.
#
# The body is handed straight to ERB.new(...).result so an attacker
# who controls the body reaches the Ruby expression evaluator.
require 'erb'
def run(body)
ERB.new(body).result
end