{"id":"CVE-2025-1686","aliases":["EUVD-2025-5321","GHSA-p75g-cxfj-7wrx","ROOT-APP-MAVEN-CVE-2025-1686"],"status":"published","title":"Pebble has Arbitrary Local File Inclusion (LFI) Vulnerability via `include` macro","description":"Versions of the package io.pebbletemplates:pebble from 0 and before 4.1.0 are vulnerable to External Control of File Name or Path via the include tag. A high privileged attacker can access sensitive local files by crafting malicious notification templates that leverage this tag to include files like /etc/passwd or /proc/1/environ.\r\r Workaround\r\rThis vulnerability can be mitigated by disabling the include macro in Pebble Templates:\r\rjava\rnew PebbleEngine.Builder()\r            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\r                    .disallowedTokenParserTags(List.of(\"include\"))\r                    .build())\r            .build();","severity":{"version":"4.0","score":6.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:P","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00847,"percentile":0.58517,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-73"],"published":"2025-02-27T05:00:05Z","modified":"2026-10-28T10:59:18Z","fixes":[{"ecosystem":"Root:Maven","package":"io.pebbletemplates:pebble","fixed_in":["3.2.1-aikido.1"],"sources":["osv"]},{"ecosystem":"Root:Maven","package":"io.root.io.pebbletemplates:pebble","fixed_in":["3.2.1-root.io.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"Maven","package":"io.pebbletemplates:pebble","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"3.2.3"}]}]},{"source":"osv","ecosystem":"Maven","package":"io.pebbletemplates:pebble","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"3.2.3"}]}],"versions":["2.5.0","2.5.1","2.6.0","2.6.1","2.6.2","3.0.0","3.0.0.BETA01","3.0.1","3.0.10","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.1.5","3.1.6","3.2.0","3.2.1","3.2.2","3.2.3"]},{"source":"osv","ecosystem":"Root:Maven","package":"io.pebbletemplates:pebble","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.2.1-aikido.1"}]}]},{"source":"osv","ecosystem":"Root:Maven","package":"io.root.io.pebbletemplates:pebble","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.2.1-root.io.1"}]}]}],"products":[{"vendor":"pebbletemplates","product":"pebble_templates"}],"references":[{"url":"https://security.snyk.io/vuln/SNYK-JAVA-IOPEBBLETEMPLATES-8745594","tags":["exploit","Exploit","Third Party Advisory","web"]},{"url":"https://github.com/PebbleTemplates/pebble/issues/680","tags":["Issue Tracking","report","web"]},{"url":"https://pebbletemplates.io/wiki/tag/include","tags":["Product","web"]},{"url":"https://github.com/PebbleTemplates/pebble/issues/688","tags":["Issue Tracking","Vendor Advisory","report","web"]},{"url":"https://github.com/PebbleTemplates/pebble/commit/b3451c8f305a1a248fbcc2363fd307d0baaee329","tags":["Patch","fix","web"]},{"url":"https://github.com/PebbleTemplates/pebble/pull/715","tags":["Issue Tracking","Patch","fix","web"]},{"url":"https://github.com/JLLeitschuh/security-research/security/advisories/GHSA-p75g-cxfj-7wrx","tags":["web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-1686","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-p75g-cxfj-7wrx"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/1xxx/CVE-2025-1686.json","tags":["advisory"]},{"url":"https://github.com/PebbleTemplates/pebble","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2025-1686","description":"Versions of the package io.pebbletemplates:pebble from 0 and before 4.1.0 are vulnerable to External Control of File Name or Path via the include tag. A high privileged attacker can access sensitive local files by crafting malicious notification templates that leverage this tag to include files like /etc/passwd or /proc/1/environ.\r\r Workaround\r\rThis vulnerability can be mitigated by disabling the include macro in Pebble Templates:\r\rjava\rnew PebbleEngine.Builder()\r            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\r                    .disallowedTokenParserTags(List.of(\"include\"))\r                    .build())\r            .build();","status":"published","published":"2025-02-27T05:00:05.848Z","modified":"2026-04-19T07:54:57.303Z","cvss":[{"version":"4.0","score":6.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:P","level":"medium","assessor":"cna"},{"version":"3.1","score":6.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N/E:P","level":"medium","assessor":"cna"}],"cwes":["CWE-73","CWE-73"],"updated_at":"2026-11-02T14:32:49.824855Z"}],"euvd":[{"id":"EUVD-2025-5321","description":"Versions of the package io.pebbletemplates:pebble from 0 and before 4.1.0 are vulnerable to External Control of File Name or Path via the include tag. A high privileged attacker can access sensitive local files by crafting malicious notification templates that leverage this tag to include files like /etc/passwd or /proc/1/environ.\r\r Workaround\r\rThis vulnerability can be mitigated by disabling the include macro in Pebble Templates:\r\rjava\rnew PebbleEngine.Builder()\r            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\r                    .disallowedTokenParserTags(List.of(\"include\"))\r                    .build())\r            .build();","status":"published","published":"2025-02-27T05:00:05Z","modified":"2026-04-19T07:54:57Z","cvss":[{"version":"4.0","score":6.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:P","level":"medium"}],"updated_at":"2026-11-02T19:24:23.330761Z"}],"ghsa":[{"id":"GHSA-p75g-cxfj-7wrx","title":"Pebble has Arbitrary Local File Inclusion (LFI) Vulnerability via `include` macro","description":"### Summary\n\nIf untrusted user input is used to dynamically create a `PebbleTemplate` with the method `PebbleEngine#getLiteralTemplate`, then an attacker can include arbitrary local files from the file system into the generated template, leaking potentially sensitive information into the output of `PebbleTemplate#evaluate`. This is done via the `include` macro.\n\n### Details\n\nThe `include` macro calls `PebbleTempateImpl#resolveRelativePath` with the `relativePath` argument passed within the template:\n\nExample template:\n```\n{% include [relativePath] %}\n```\nWhen `resolveRelativePath` is called, the `relativePath`  is resolved against the `PebbleTemplateImpl.name` variable.\n\n```java\n  /**\n   * This method resolves the given relative path based on this template file path.\n   *\n   * @param relativePath the path which should be resolved.\n   * @return the resolved path.\n   */\n  public String resolveRelativePath(String relativePath) {\n    String resolved = this.engine.getLoader().resolveRelativePath(relativePath, this.name);\n    if (resolved == null) {\n      return relativePath;\n    } else {\n      return resolved;\n    }\n  }\n```\nhttps://github.com/PebbleTemplates/pebble/blob/82ad7fcf9e9eaa45ee82ae3335a1409d19c10263/pebble/src/main/java/io/pebbletemplates/pebble/template/PebbleTemplateImpl.java#L380\n\nUnfortunately, when the template is created from a string, as is the case when `PebbleEngine#getLiteralTemplate` is used, the `PebbleTemplateImpl.name` variable is actually the entirety of the contents of the template, not a filename as the logic expects. The net result is that the `relativePath` is resolved against the system root directory. As a result, files accessible from the root directory of the filesystem can be included into a template. \n\n### PoC\n\nThe following test demonstrates the vulnerability:\n\n```java\nPebbleEngine e = new PebbleEngine.Builder().build();\n\nString templateString = \"\"\"\n        {% include '/etc/passwd' %}\n        \"\"\";\nPebbleTemplate template = e.getLiteralTemplate(templateString);\n\ntry (final Writer writer = new StringWriter()) {\n    template.evaluate(writer, new HashMap\u003c\u003e());\n    System.out.println(writer);\n}\n```\n\nAs an attacker, the following malicious template demonstrates the vulnerability:\n\n```\n{% include '/etc/passwd' %}\n```\n\n### Impact\n\nThis is an arbitrary  Local File Inclusion (LFI) vulnerability. It can allow attackers to exfiltrate the contents of the local filesystem, including sensitive files into `PebbleTemplate` output. This can also be used to access the `/proc` filesystem which can give an attacker access to environment variables.\n\n### Fix\n\nThere exists no published fix for this vulnerability. The best way to mitigate this vulnerability is to disable the `include` macro in Pebble Templates.\n\nThe following can safeguard your application from this vulnerability:\n\n```java\nnew PebbleEngine.Builder()\n            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\n                    .disallowedTokenParserTags(List.of(\"include\"))\n                    .build())\n            .build();\n```\n\n### Report Timeline\n\nVulnerability was reported under the Open Source Security Foundation (OpenSSF) [Model Outbound Vulnerability Disclosure Policy: Version 0.1](https://openssf.org/about/vulnerability-disclosure-policy/).\n\n - [Jul 15, 2024](https://github.com/PebbleTemplates/pebble/issues/680#issue-2409727829) Maintainer Contacted to enable private vulnerability reporting\n - [Jul 18, 2024](https://github.com/PebbleTemplates/pebble/issues/680#issuecomment-2236970984) I opened a GHSA \n to report this vulnerability to the maintainer https://github.com/PebbleTemplates/pebble/security/advisories/GHSA-7c6h-hmf9-7wj7 (private link)\n - Jul 29, 2024 GHSA updated to ping maintainer about vulnerability, no response\n - Oct 1, 2024 GHSA updated to ping maintainer about vulnerability, no response\n - Nov 15, 2024 GHSA updated to inform maintainer that disclosure timeline had lapsed, no response.\n - Feb 19, 2025 GHSA updated to inform maintainer that disclosure would occur imminently, no response.\n - Feb 24, 2025 this GHSA was created to disclose this vulnerability **without a patch available**.\n\nFor further discussion, see this issue: https://github.com/PebbleTemplates/pebble/issues/688\n\n### Credit\n\nThis vulnerability was discovered by @JLLeitschuh while at [Chainguard Labs](https://www.chainguard.dev). Jonathan is currently independent.","status":"published","published":"2025-02-28T19:45:03Z","modified":"2026-04-24T20:55:23Z","cvss":[{"version":"4.0","score":7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:H/VA:H/SC:L/SI:N/SA:N","level":"high"},{"version":"3.1","score":6.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-73"],"updated_at":"2026-11-02T14:39:57.650091Z"}],"nvd":[{"id":"CVE-2025-1686","description":"Versions of the package io.pebbletemplates:pebble from 0 and before 4.1.0 are vulnerable to External Control of File Name or Path via the include tag. A high privileged attacker can access sensitive local files by crafting malicious notification templates that leverage this tag to include files like /etc/passwd or /proc/1/environ.\r\r Workaround\r\rThis vulnerability can be mitigated by disabling the include macro in Pebble Templates:\r\rjava\rnew PebbleEngine.Builder()\r            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\r                    .disallowedTokenParserTags(List.of(\"include\"))\r                    .build())\r            .build();","status":"published","published":"2025-02-27T05:15:14.143Z","modified":"2026-06-17T08:39:35.997Z","cvss":[{"version":"4.0","score":4.8,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"medium","assessor":"secondary"},{"version":"3.1","score":6.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N","level":"medium","assessor":"secondary"},{"version":"3.1","score":4.9,"vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-73"],"updated_at":"2026-11-02T14:10:52.398004Z"}],"osv":[{"id":"CVE-2025-1686","description":"Versions of the package io.pebbletemplates:pebble from 0 and before 4.1.0 are vulnerable to External Control of File Name or Path via the include tag. A high privileged attacker can access sensitive local files by crafting malicious notification templates that leverage this tag to include files like /etc/passwd or /proc/1/environ.\r\r Workaround\r\rThis vulnerability can be mitigated by disabling the include macro in Pebble Templates:\r\rjava\rnew PebbleEngine.Builder()\r            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\r                    .disallowedTokenParserTags(List.of(\"include\"))\r                    .build())\r            .build();","status":"published","published":"2025-02-27T05:00:05.848Z","modified":"2026-10-28T10:59:18.279387929Z","cvss":[{"version":"4.0","score":4.8,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N/E:P","level":"medium"}],"cwes":["CWE-73"],"updated_at":"2026-11-02T15:44:46.340268Z"},{"id":"GHSA-p75g-cxfj-7wrx","title":"Pebble has Arbitrary Local File Inclusion (LFI) Vulnerability via `include` macro","description":"### Summary\n\nIf untrusted user input is used to dynamically create a `PebbleTemplate` with the method `PebbleEngine#getLiteralTemplate`, then an attacker can include arbitrary local files from the file system into the generated template, leaking potentially sensitive information into the output of `PebbleTemplate#evaluate`. This is done via the `include` macro.\n\n### Details\n\nThe `include` macro calls `PebbleTempateImpl#resolveRelativePath` with the `relativePath` argument passed within the template:\n\nExample template:\n```\n{% include [relativePath] %}\n```\nWhen `resolveRelativePath` is called, the `relativePath`  is resolved against the `PebbleTemplateImpl.name` variable.\n\n```java\n  /**\n   * This method resolves the given relative path based on this template file path.\n   *\n   * @param relativePath the path which should be resolved.\n   * @return the resolved path.\n   */\n  public String resolveRelativePath(String relativePath) {\n    String resolved = this.engine.getLoader().resolveRelativePath(relativePath, this.name);\n    if (resolved == null) {\n      return relativePath;\n    } else {\n      return resolved;\n    }\n  }\n```\nhttps://github.com/PebbleTemplates/pebble/blob/82ad7fcf9e9eaa45ee82ae3335a1409d19c10263/pebble/src/main/java/io/pebbletemplates/pebble/template/PebbleTemplateImpl.java#L380\n\nUnfortunately, when the template is created from a string, as is the case when `PebbleEngine#getLiteralTemplate` is used, the `PebbleTemplateImpl.name` variable is actually the entirety of the contents of the template, not a filename as the logic expects. The net result is that the `relativePath` is resolved against the system root directory. As a result, files accessible from the root directory of the filesystem can be included into a template. \n\n### PoC\n\nThe following test demonstrates the vulnerability:\n\n```java\nPebbleEngine e = new PebbleEngine.Builder().build();\n\nString templateString = \"\"\"\n        {% include '/etc/passwd' %}\n        \"\"\";\nPebbleTemplate template = e.getLiteralTemplate(templateString);\n\ntry (final Writer writer = new StringWriter()) {\n    template.evaluate(writer, new HashMap\u003c\u003e());\n    System.out.println(writer);\n}\n```\n\nAs an attacker, the following malicious template demonstrates the vulnerability:\n\n```\n{% include '/etc/passwd' %}\n```\n\n### Impact\n\nThis is an arbitrary  Local File Inclusion (LFI) vulnerability. It can allow attackers to exfiltrate the contents of the local filesystem, including sensitive files into `PebbleTemplate` output. This can also be used to access the `/proc` filesystem which can give an attacker access to environment variables.\n\n### Fix\n\nThere exists no published fix for this vulnerability. The best way to mitigate this vulnerability is to disable the `include` macro in Pebble Templates.\n\nThe following can safeguard your application from this vulnerability:\n\n```java\nnew PebbleEngine.Builder()\n            .registerExtensionCustomizer(new DisallowExtensionCustomizerBuilder()\n                    .disallowedTokenParserTags(List.of(\"include\"))\n                    .build())\n            .build();\n```\n\n### Report Timeline\n\nVulnerability was reported under the Open Source Security Foundation (OpenSSF) [Model Outbound Vulnerability Disclosure Policy: Version 0.1](https://openssf.org/about/vulnerability-disclosure-policy/).\n\n - [Jul 15, 2024](https://github.com/PebbleTemplates/pebble/issues/680#issue-2409727829) Maintainer Contacted to enable private vulnerability reporting\n - [Jul 18, 2024](https://github.com/PebbleTemplates/pebble/issues/680#issuecomment-2236970984) I opened a GHSA \n to report this vulnerability to the maintainer https://github.com/PebbleTemplates/pebble/security/advisories/GHSA-7c6h-hmf9-7wj7 (private link)\n - Jul 29, 2024 GHSA updated to ping maintainer about vulnerability, no response\n - Oct 1, 2024 GHSA updated to ping maintainer about vulnerability, no response\n - Nov 15, 2024 GHSA updated to inform maintainer that disclosure timeline had lapsed, no response.\n - Feb 19, 2025 GHSA updated to inform maintainer that disclosure would occur imminently, no response.\n - Feb 24, 2025 this GHSA was created to disclose this vulnerability **without a patch available**.\n\nFor further discussion, see this issue: https://github.com/PebbleTemplates/pebble/issues/688\n\n### Credit\n\nThis vulnerability was discovered by @JLLeitschuh while at [Chainguard Labs](https://www.chainguard.dev). Jonathan is currently independent.","status":"published","published":"2025-02-28T19:45:03Z","modified":"2026-09-10T03:50:22.817579012Z","cvss":[{"version":"3.1","score":6.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N","level":"medium"},{"version":"4.0","score":7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:H/VA:H/SC:L/SI:N/SA:N","level":"high"}],"cwes":["CWE-73"],"updated_at":"2026-11-02T15:46:52.891208Z"},{"id":"ROOT-APP-MAVEN-CVE-2025-1686","title":"CVE-2025-1686 in io.pebbletemplates:pebble - Patched by Root","description":"Root has patched CVE-2025-1686 in the io.pebbletemplates:pebble package for Root:Maven. Multiple fixed versions available.","status":"published","published":"2026-10-01T09:34:44Z","modified":"2026-10-01T10:15:02.881236134Z","updated_at":"2026-11-02T15:53:27.066589Z"}]}}
