Reading — step 1 of 5
Read
Variable Resolution
Inside {{ ... }}: a path. Resolve against context (a dict).
Simple:
context = {'name': 'Alice'}
{{ name }} -> "Alice"
Nested:
context = {'user': {'name': 'Alice', 'age': 30}}
{{ user.name }} -> "Alice"
Lists:
context = {'items': [10, 20, 30]}
{{ items[0] }} -> "10"
{{ items.0 }} -> "10" (some engines)
Method calls (Jinja2):
{{ items.append(40) }} # mutates list
{{ name.upper() }} # "ALICE"
Resolution algorithm:
Strict mode: raise on missing variables. Default mode: silently substitute empty string.
Globals: some engines have a builtin namespace (lookup vars first in context, fallback to globals).
Local scope: {% for x in items %}{{ x }}{% endfor %} introduces local var x.
Be careful with security: if context contains user-controlled data and template engine evaluates Python (__class__, __subclasses__, etc.), you have RCE. Server-Side Template Injection (SSTI).
Mitigations:
- Sandbox: restrict attribute access (no
__attrs__). - Whitelist methods (no
os.system). - Don't pass user input as TEMPLATE; only as DATA.
Real CVEs from SSTI in Flask/Jinja2 = remote code execution on web servers.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…