fsspec: Server-Side Template Injection in ReferenceFileSystem leads to Remote Code Execution
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.
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 .
All in fsspec/implementations/reference.py :
Sink C is the most severe: it is reached unconditionally for any references JSON that includes a gen field.
Proof of concept (Sink C, minimal)
End-to-end via xarray (real-world consumer pathway)
fsspec 2025.10.0, jinja2 3.1.6, Python 3.9, macOS 14
fsspec 2025.10.0, jinja2 3.1.6, Python 3.12-slim, Docker Linux
fsspec.ReferenceFileSystem is the canonical entrypoint for the Kerchunk format, widely used in the Pangeo / Earth-observation / climate data-science ecosystem to provide cloud-optimised views of HDF5 / NetCDF / GRIB archives hosted on object storage.
Realistic attack vectors:
A user opens a community-shared Kerchunk catalogue link via xarray/dask.
A managed data-science platform (notebook server, batch job runner) ingests user-submitted Kerchunk URLs.
A workflow downloads a catalogue from a bucket whose contents have been tampered with (supply chain).
In every case, the victim performs no action beyond opening a "reference filesystem" — there is no documented expectation that a data catalogue can execute arbitrary Python code.
Replace jinja2.Template(...) with a shared jinja2.sandbox.ImmutableSandboxedEnvironment for all three sinks. This matches the post-incident hardening applied to llama-cpp-python after CVE-2024-34359 .
Then in each sink, replace jinja2.Template(s).render(...) with _sandboxed_env().from_string(s).render(...) .
The legitimate Kerchunk template syntax (simple variable substitution like {{ varname }} ) continues to work under the sandbox; only the SSTI gadgets ( __class__ , __init__.__globals__ , __subclasses__ , etc.) are refused with jinja2.exceptions.SecurityError .
A complete patch is available on request.
fsspec/filesystem_spec#2029
fsspec/filesystem_spec#2039
fsspec/filesystem_spec@ 8643878
fsspec/filesystem_spec@ a1c16ab
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
