{"id":"CVE-2026-54550","aliases":["GHSA-f63g-88cj-hjf9"],"url":"https://o3.security/vulnerability/CVE-2026-54550","summary":"IzPack: Path Traversal in UnpackerBase allows writing files outside the installation directory via malicious pack entries","details":"### Summary\n\nIzPack's `UnpackerBase.unpack()` resolves pack-file target paths without any\ncanonical-path or directory-containment check. An attacker who distributes a\ntrojanized installer JAR (the format is unsigned) can include pack entries whose\n`targetPath` contains `../` sequences. When a victim runs the installer the\nfile is written to an attacker-chosen location on disk under the victim's\nprivileges — including startup folders, PATH directories, or system locations.\n\n### Details\n\n**Vulnerable method:** `com.izforge.izpack.installer.unpacker.UnpackerBase.unpack()`\n**Source file:** `izpack-installer/src/main/java/com/izforge/izpack/installer/unpacker/UnpackerBase.java`\n**Vulnerable lines (5.2.4):** ~618–627\n\nThe relevant code path is:\n\n```java\nString targetPath = packFile.getTargetPath();             // attacker-controlled\nString path       = IoHelper.translatePath(targetPath, variables); // separator swap ONLY\nFile   target     = new File(path);                       // no canonical check\n// ... mkdirs() then file is written to `target`\n```\n\n`IoHelper.translatePath()` (source: `izpack-util/.../IoHelper.java`) performs\n**only** file-separator character conversion (`'/'` ↔ `File.separatorChar`) and\ncontains no security validation whatsoever. There is no call to\n`getCanonicalPath()`, no `startsWith(installDir)` containment check, and no\nnormalisation of `..` segments.\n\nBecause IzPack installer JARs carry **no digital signature**, an attacker can\nrepack any legitimate installer with malicious `PackFile` entries. The file\nformat is a standard ZIP with serialised resources — no integrity protection.\n\n**Confirmed unpatched in HEAD (fetched from GitHub, 2025):**\n```\ngit show HEAD:izpack-installer/src/main/java/com/izforge/izpack/installer/unpacker/UnpackerBase.java \\\n  | grep -n 'getCanonicalPath\\|startsWith.*install\\|traversal'\n# (no output — fix not present)\n```\n\n### PoC\n\n```bash\n# 1. Clone IzPack source and view the vulnerable code directly\ngit clone --depth=1 --branch izpack-5.2.4 https://github.com/izpack/izpack.git\nsed -n '615,650p' izpack/izpack-installer/src/main/java/com/izforge/izpack/installer/unpacker/UnpackerBase.java\n\n# 2. Compile and run the following Java reproducer (no IzPack classpath needed):\n```\n\n```java\n// TestPathTraversal.java\nimport java.io.*;\n\npublic class TestPathTraversal {\n    // Exact replication of IoHelper.translatePath() — separator swap, no security\n    static String translatePath(String destination) {\n        return destination.replace('/', File.separatorChar);\n    }\n\n    public static void main(String[] args) throws Exception {\n        String installDir   = \"/tmp/izpack_install\";\n        String maliciousPath = installDir + \"/../../../tmp/ESCAPED_FILE\";\n\n        // This is what UnpackerBase does:\n        String path   = translatePath(maliciousPath);\n        File   target = new File(path);           // resolves traversal\n        target.getParentFile().mkdirs();\n        try (FileWriter fw = new FileWriter(target)) {\n            fw.write(\"Written outside install dir via IzPack path traversal\\n\");\n        }\n        System.out.println(\"File written to: \" + target.getCanonicalPath());\n        System.out.println(\"Inside installDir: \" +\n            target.getCanonicalPath().startsWith(new File(installDir).getCanonicalPath()));\n    }\n}\n```\n\n```bash\njavac TestPathTraversal.java && java TestPathTraversal\n# Output: File written to: /tmp/ESCAPED_FILE\n#         Inside installDir: false\n```\n\n### Impact\n\nAny user who runs an IzPack-generated installer is affected. The attacker only\nneeds to distribute a repackaged installer — a common social-engineering vector.\nOn Windows (the primary IzPack platform) the victim typically runs the installer\nas a local administrator, so the attacker can write to `%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup`,\n`%SystemRoot%\\System32`, or any other location reachable by the victim user.\nOn Linux/macOS the same applies for user-writable locations.\n\nNo authentication, no special privileges and no interaction beyond running the\ninstaller are required on the victim side.\n\n### Credits\nThis issue was identified by Michał Majchrowicz, Marcin Wyczechowski, and Paweł Zdunek, members of the AFINE Team.","published":"2026-08-26T14:24:06.879Z","modified":"2026-09-11T08:19:28.680174Z","cvss":{"score":7.4,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:N"},"epss":{"score":0.00377,"percentile":0.3054,"asOf":"2026-08-27"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Maven","name":"org.codehaus.izpack:izpack-installer","fixedVersion":null}],"fix":{"url":"https://github.com/izpack/izpack/commit/4233ba38d0f1825f9cf3e0204e5261a5498e29d8","label":"izpack/izpack@4233ba3"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54550.json"},{"type":"ADVISORY","url":"https://github.com/izpack/izpack/security/advisories/GHSA-f63g-88cj-hjf9"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-54550"},{"type":"FIX","url":"https://github.com/izpack/izpack/commit/4233ba38d0f1825f9cf3e0204e5261a5498e29d8"},{"type":"FIX","url":"https://github.com/izpack/izpack/commit/8b7c6792c4fe85e3b1759c106aae39b904848466"},{"type":"FIX","url":"https://github.com/izpack/izpack/pull/1193"},{"type":"PACKAGE","url":"https://github.com/izpack/izpack"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-11T08:19:28.680174Z"}}