{
  "schema_version": "1.4.0",
  "id": "GHSA-p75g-cxfj-7wrx",
  "modified": "2025-02-28T19:45:03Z",
  "published": "2025-02-28T19:45:03Z",
  "aliases": [
    "CVE-2025-1686"
  ],
  "summary": "Pebble has Arbitrary Local File Inclusion (LFI) Vulnerability via `include` macro",
  "details": "### 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<>());\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.",
  "severity": [
    {
      "type": "CVSS_V3",
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N"
    },
    {
      "type": "CVSS_V4",
      "score": "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"
    }
  ],
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "io.pebbletemplates:pebble"
      },
      "ranges": [
        {
          "type": "ECOSYSTEM",
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "3.2.3"
            }
          ]
        }
      ]
    }
  ],
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/JLLeitschuh/security-research/security/advisories/GHSA-p75g-cxfj-7wrx"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-1686"
    },
    {
      "type": "WEB",
      "url": "https://github.com/PebbleTemplates/pebble/issues/680"
    },
    {
      "type": "WEB",
      "url": "https://github.com/PebbleTemplates/pebble/issues/688"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/PebbleTemplates/pebble"
    },
    {
      "type": "WEB",
      "url": "https://pebbletemplates.io/wiki/tag/include"
    },
    {
      "type": "WEB",
      "url": "https://security.snyk.io/vuln/SNYK-JAVA-IOPEBBLETEMPLATES-8745594"
    }
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "severity": "HIGH",
    "github_reviewed": true,
    "github_reviewed_at": "2025-02-28T19:45:03Z",
    "nvd_published_at": "2025-02-27T05:15:14Z"
  }
}