Skip to content

FIX: Detect multi-engine RCE gadgets in SSTIOutputScorer - #3541

Open
Vardhman Gupta (Kaap10) wants to merge 1 commit into
microsoft:mainfrom
Kaap10:feat/ssti-multi-engine-rce-gadgets
Open

Vardhman Gupta (Kaap10) wants to merge 1 commit into
microsoft:mainfrom
Kaap10:feat/ssti-multi-engine-rce-gadgets

Conversation

@Kaap10

Copy link
Copy Markdown
Contributor

Description

SSTIOutputScorer detects server-side template injection (SSTI) payloads emitted in LLM responses (OWASP LLM02).
While the docstring explicitly states:

"a model can be coaxed into emitting a template expression that a downstream rendering engine (Jinja2, Twig, Freemarker, ERB, Velocity) will evaluate, leading to data disclosure or remote code execution."

The default patterns previously only covered basic arithmetic (\d+ * \d+) and Python-specific sandbox escapes (__class__), completely missing remote code execution gadgets for non-Python template engines commonly used across enterprise systems (Java, PHP):

  1. Apache FreeMarker: Utility class instantiation (freemarker.template.utility.Execute, ObjectConstructor, JythonRuntime) via ?new().
  2. Apache Velocity: Reflection and runtime execution chains (#set($rt=...forName("java.lang.Runtime")), $class.inspect, .getRuntime().exec(), .ProcessBuilder).
  3. Twig (PHP): Dangerous PHP execution filters (|filter('system'), |map('system'), |reduce('system')) and _self.env.registerUndefinedFilterCallback.
  4. Spring Expression Language (SpEL) / Thymeleaf: Java type evaluation into java.lang.Runtime, java.lang.ProcessBuilder, or javax.script (${T(java.lang.Runtime)...}, ${T(Runtime)...}).

This PR extends _DEFAULT_PATTERNS in SSTIOutputScorer with high-precision patterns targeting these canonical exploitation gadgets, while keeping existing patterns and custom overrides completely untouched.

Fixes #3540

Tests and Documentation

  • Added 21 positive test cases in tests/unit/score/regex/test_ssti_output_scorer.py covering FreeMarker, Apache Velocity, Twig (including multiline and whitespace variations), and SpEL (both bare T(Runtime) and fully qualified forms).
  • Added 9 negative control cases verifying that standard template variables, benign filters ({{ names|filter(v => v > 0) }}), benign type references (${T(Math).min(1, 2)}), and shell variables ($100, $user) are not flagged.
  • Added rationale assertions verifying each new pattern name is included in score.score_rationale.
  • All 69 unit tests in test_ssti_output_scorer.py passing cleanly in ~11s.
  • All 1,138 tests across the entire tests/unit/score/regex/ test suite passing with zero regressions.
  • Code style and formatting verified with ruff check and ruff format.

Detect canonical remote code execution gadgets for Apache FreeMarker, Apache Velocity, Twig, and Spring/SpEL in SSTIOutputScorer.

Fixes microsoft#3540

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: SSTIOutputScorer misses RCE exploitation gadgets for FreeMarker, Velocity, Twig, and Spring/SpEL

1 participant