{"id":"GHSA-8p4x-wr7x-3788","summary":"python-liquid: Absolute paths escape filesystem loader search path","details":"### Impact\nThe 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.\n\n### Patches\nThe 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`.\n\n```python\n        if os.path.pardir in template_path.parts or template_path.is_absolute():\n            raise TemplateNotFoundError(template_name)\n```\n\n### Workarounds\n\nCreate 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. \n\n```python\nimport os\nfrom pathlib import Path\n\nfrom liquid import Environment\nfrom liquid import FileSystemLoader\nfrom liquid.exceptions import TemplateNotFoundError\n\n\nclass MyFileSystemLoader(FileSystemLoader):\n    def resolve_path(self, template_name: str) -\u003e Path:\n        template_path = Path(template_name)\n\n        if self.ext and not template_path.suffix:\n            template_path = template_path.with_suffix(self.ext)\n\n        if os.path.pardir in template_path.parts or template_path.is_absolute():\n            raise TemplateNotFoundError(template_name)\n\n        for path in self.search_path:\n            source_path = path.joinpath(template_path)\n            if not source_path.exists():\n                continue\n            return source_path\n\n        raise TemplateNotFoundError(template_name)\n\n\nenv = Environment(loader=MyFileSystemLoader(\"path/to/templates/\"))\n```","aliases":["CVE-2026-45017","PYSEC-2026-192"],"modified":"2026-09-10T03:51:04.993437942Z","published":"2026-05-11T14:57:43Z","database_specific":{"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-05-11T14:57:43Z","nvd_published_at":"2026-05-28T16:16:25Z","cwe_ids":["CWE-22"]},"references":[{"type":"WEB","url":"https://github.com/jg-rp/liquid/security/advisories/GHSA-8p4x-wr7x-3788"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-45017"},{"type":"PACKAGE","url":"https://github.com/jg-rp/liquid"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/python-liquid/PYSEC-2026-192.yaml"}],"affected":[{"package":{"name":"python-liquid","ecosystem":"PyPI","purl":"pkg:pypi/python-liquid"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.0"}]}],"versions":["0.10.0","0.10.1","0.11.0","0.5.1","0.5.2","0.5.3","0.5.5","0.5.6","0.6.0","0.6.1","0.6.2","0.6.3","0.6.4","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.7.5","0.7.6","0.7.7","0.8.0","0.8.1","0.9.0","1.0.0","1.0.1","1.0.2","1.0.3","1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.10.0","1.10.2","1.11.0","1.12.0","1.12.1","1.12.2","1.13.0","1.2.0","1.2.1","1.3.0","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.5.0","1.5.1","1.6.0","1.6.1","1.7.0","1.8.0","1.8.1","1.9.0","1.9.1","1.9.2","1.9.3","1.9.4","2.0.0","2.0.1","2.0.2","2.1.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-8p4x-wr7x-3788/GHSA-8p4x-wr7x-3788.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N"}]}