fsspec: Server-Side Template Injection in ReferenceFileSystem leads to Remote Code Execution
Summary
fsspec.implementations.reference.ReferenceFileSystem parses a "references"
JSON document (Kerchunk format) supplied either inline or via a URL. The
parser renders fields from this JSON through un-sandboxed
jinja2.Template(...).render(...) calls in three locations. An attacker who
controls the JSON document — typically by hosting it at a URL that the
victim opens with fsspec.filesystem("reference", fo=URL) or via
xarray.open_dataset("reference://...") — achieves arbitrary Python code
execution on the victim machine, before any data is read.
This mirrors the pattern of CVE-2024-34359
in llama-cpp-python, where externally-sourced template strings were
rendered with the default unrestricted Jinja2 environment.
Affected versions
All versions of fsspec from 0.9.0 onward (vulnerable code introduced in
commit 0fb8d56b684ee74ad9ad4587fd560bde1b116450, 2021-03-12). Confirmed on
the latest released version 2025.10.0.
Affected sinks
All in fsspec/implementations/reference.py:
| Sink | Location | Trigger |
|---|---|---|
A — _process_references1._render_jinja |
lines 1016-1018 | simple_templates=False and a refs entry contains {{ |
B — _process_templates (lambda) |
lines 1043-1053 | templates dict has values containing {{, invoked later via render context |
C — _process_gen |
lines 1075-1083 | references JSON contains a gen array (always reached, regardless of simple_templates) |
Sink C is the most severe: it is reached unconditionally for any references
JSON that includes a gen field.
The vulnerable code:
# fsspec/implementations/reference.py
# Sink A
@lru_cache(1000)
def _render_jinja(u):
return jinja2.Template(u).render(**self.templates) #