CVE-2026-45017 — python-liquid
CVE-2026-45017 is a Path Traversal vulnerability in python-liquid. A fix is available for python-liquid — see the affected versions and patch details below.
Python Liquid: Absolute paths escape filesystem loader search path
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-45017.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
Real-World Exposure
python-liquidReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Impact
The built-in FileSystemLoader and CachingFileSystemLoader do not guard against reading files outside their search paths when given an absolute path to resolve. This allows malicious template authors to load and render arbitrary files via the {% include %} and {% render %} tags. Targeted files would need to contain valid Liquid markup and be readable by the application process.
Patches
The issue is fixed in version 2.2.0 with the inclusion of a template_path.is_absolute() condition in liquid/builtin/loaders/file_system_loader.py.
if os.path.pardir in template_path.parts or template_path.is_absolute():
raise TemplateNotFoundError(template_name)
Workarounds
Create a custom template loader by inheriting from FileSystemLoader and overriding resolve_path(). Use an instance of the custom loader as the loader argument when instantiating your Liquid environment.
import os
from pathlib import Path
from liquid import Environment
from liquid import FileSystemLoader
from liquid.exceptions import TemplateNotFoundError
class MyFileSystemLoader(FileSystemLoader):
def resolve_path(self, template_name: str) -> Path:
template_path = Path(template_name)
if self.ext and not template_path.suffix:
template_path = template_path.with_suffix(self.ext)
if os.path.pardir in template_path.parts or template_path.is_absolute():
raise TemplateNotFoundError(template_name)
for path in self.search_path:
source_path = path.joinpath(template_path)
if not source_path.exists():
continue
return source_path
raise TemplateNotFoundError(template_name)
env = Environment(loader=MyFileSystemLoader("path/to/templates/"))
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | python-liquid | all versions | 2.2.0pip install --upgrade 'python-liquid==2.2.0' |
Affected Products
python liquidjg-rpDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for python-liquid, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update python-liquid to 2.2.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-45017 is resolved across your whole dependency graph.
Workarounds
Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.
Frequently Asked Questions
Is CVE-2026-45017 in your dependencies?
Find it across PyPI, including transitive dependencies.