{"id":"CVE-2026-42078","aliases":["GHSA-hrcw-xc63-g29m","PYSEC-2026-2893"],"url":"https://o3.security/vulnerability/CVE-2026-42078","summary":"PPTAgent: Arbitrary File Write + Directory Creation via markdown_table_to_image","details":"### Summary\n\nThe `markdown_table_to_image` tool accepts a caller-controlled path parameter and passes it directly to `get_html_table_image`:\n\n```python\n# pptagent/mcp_server.py:127-143\ndef markdown_table_to_image(markdown_table: str, path: str, css: str) -> str:\n    \"\"\"\n    Args:\n        path (str): The file path where the image will be saved\n    \"\"\"\n    html = markdown_to_html(markdown_table)\n    get_html_table_image(html, path, css)           # ← no path validation\n    return f\"Markdown table converted to image and saved to {path}\"\n\n# pptagent/utils.py:337-366\ndef get_html_table_image(html: str, output_path: str, css: str = None):\n    parent_dir, base_name = os.path.split(output_path)\n    if parent_dir and not os.path.exists(parent_dir):\n        os.makedirs(parent_dir)                     # ← creates arbitrary directories\n    hti = Html2Image(...)\n    hti.screenshot(\n        html_str=html,\n        css_str=css,\n        save_as=base_name,                          # ← writes image to any directory\n        size=(1000, 600),\n    )\n```\n\n`os.makedirs(parent_dir)` creates arbitrary directory trees, and `Html2Image.screenshot` writes the rendered image to `parent_dir/base_name`. Unlike `download_file` in the same project, there is no `is_relative_to(workspace)` guard. This behaviour can be fixed with the same pattern as the above.\n\n\n### Impact\n\nThe concrete attack scenarios include\n\n- SSH key replacement: `path = \"/home/user/.ssh/authorized_keys\"` — replaces the authorized_keys file with an image binary (breaks - SSH but could be an image crafted with a specific PNG/JPEG payload).\n- Web shell: `path = \"/var/www/html/uploads/shell.php\"` — writes the rendered PNG there; the file has the .php extension but PNG content; combined with Apache Options +MultiViews or file-include vulnerabilities could be dangerous.\n- Directory creation oracle: `path = \"/root/test/probe.png\"` — if the directory is created, confirms the target path exists; if it errors, reveals permissions information.","published":"2026-05-04T16:55:17.870Z","modified":"2026-08-12T03:51:13.513419649Z","cvss":{"score":4.6,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L"},"epss":{"score":0.00198,"percentile":0.09899,"asOf":"2026-08-14"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"pptagent","fixedVersion":"1.1.36"}],"fix":{"url":"https://github.com/icip-cas/PPTAgent/commit/418491a9a1c02d9d93194b5973bb58df35cf9d00","label":"icip-cas/PPTAgent@418491a"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/42xxx/CVE-2026-42078.json"},{"type":"ADVISORY","url":"https://github.com/icip-cas/PPTAgent/security/advisories/GHSA-hrcw-xc63-g29m"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42078"},{"type":"FIX","url":"https://github.com/icip-cas/PPTAgent/commit/418491a9a1c02d9d93194b5973bb58df35cf9d00"},{"type":"PACKAGE","url":"https://github.com/icip-cas/PPTAgent"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:13.513419649Z"}}