Lion Cipher Lab

Render untrusted model chat templates in a Jinja sandbox, and audit them before you load

Why it matters

You download a model from a hub, point your favourite inference library at it, and send it a chat. Before the model ever generates a token, the library has already read a Jinja2 template out of the model's own metadata and rendered it to build the prompt. If it rendered that template with a plain jinja2.Environment, the model's author - who may not be who the upload says - just ran template code in your process. That is not hypothetical: CVE-2024-34359, nicknamed 'Llama Drama', was exactly this in llama-cpp-python (versions 0.2.30 through 0.2.71), rated CVSS 9.6, and the fix in 0.2.72 was to…

What you'll learn

Steps in this lab

  1. The words first: chat template, SSTI, the object graph, dunder, sandbox, SecurityError, AST, allowlist - and the fact that no model runs
  2. Open a terminal, check Python, make a scratch folder, and install jinja2 in a virtual environment
  3. The case you are reproducing: CVE-2024-34359, and why this is not the web-SSTI fix
  4. Build the corpus: five real templates and five benign-canary ones
  5. BEFORE: render the corpus with a plain jinja2.Environment and watch all five canaries fire
  6. AFTER: switch to ImmutableSandboxedEnvironment and measure what breaks and what is blocked
  7. Add a static pre-load auditor: parse the AST for dunder access, and pin a hash allowlist
  8. The honest negatives: resource exhaustion, the auditor's blind spot, and allowlist brittleness
  9. When to reach for which control - and when NOT to
  10. Ship it: re-run, break a constant on purpose, and clean up

Open the full interactive lab →