CVE-2026-42080
PPTAgent: Arbitrary File Write via `save_generated_slides`
PPTAgent is an agentic framework for reflective PowerPoint generation. Prior to commit 418491a, there is an arbitrary file write vulnerability via save_generated_slides. This issue has been patched via commit 418491a.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- Required
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
4.6
PPTAgent: Arbitrary File Write via `save_generated_slides`
PPTAgent is an agentic framework for reflective PowerPoint generation. Prior to commit 418491a, there is an arbitrary file write vulnerability via save_generated_slides. This issue has been patched via commit 418491a.
- Record
CVE-2026-42080- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-22
- Updated
- 2026-11-02
EUVDEUVD-2026-27017
4.6
PPTAgent is an agentic framework for reflective PowerPoint generation. Prior to commit 418491a, there is an arbitrary file write vulnerability via save_generated_slides. This issue has been patched via commit 418491a.
- Record
EUVD-2026-27017- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-pxhg-7xr2-w7xg
4.6
PPTAgent: Arbitrary File Write via `save_generated_slides`
Summary
This vulnerability has been fixed in https://github.com/icip-cas/PPTAgent/commit/418491a9a1c02d9d93194b5973bb58df35cf9d00.
The save_generated_slides MCP tool accepts a pptx_path argument and writes the generated PPTX file to that path without any workspace restriction or path validation:
# pptagent/mcp_server.py:288-300
async def save_generated_slides(pptx_path: str):
"""Save the generated slides to a PowerPoint file.
Args:
pptx_path: The path to save the PowerPoint file
"""
pptx = Path(pptx_path)
assert len(self.slides), (
"No slides generated, please call `generate_slide` first"
)
pptx.parent.mkdir(parents=True, exist_ok=True) # ← creates arbitrary directories
self.empty_prs.save(pptx_path) # ← writes to arbitrary path
The call to pptx.parent.mkdir(parents=True, exist_ok=True) creates any intermediate directories, and self.empty_prs.save(pptx_path) writes a valid PPTX binary (ZIP archive) to the specified path. No is_relative_to(workspace) check is performed — contrast with download_file in deeppresenter/tools/search.py:290, which correctly enforces workspace confinement.
The server changes directory to WORKSPACE (if set) on startup, so relative paths land in the workspace. Absolute paths, however, reach any filesystem location accessible to the server process.
Impact
The concrete attack scenarios include
- Cron persistence (root-running server):
pptx_path = "/etc/cron.d/backdoor"→ writes a PPTX ZIP to a path the cron daemon reads; if the ZIP header is misinterpreted, this may corrupt cron or be exploitable depending on parser behaviour. - Dot-file overwrite:
pptx_path = "/home/user/.bashrc"→ overwrites shell init file with a binary blob containing arbitrary content in the PPTX's embedded comments/custom properties. - Directory traversal from workspace:
pptx_path = "../../.ssh/known_hosts.pptx"→ escapes workspace entirely. - Denial of service:
pptx_path = "/dev/sda"writes to a raw device.
Remediation
The potential fix is something like:
async def save_generated_slides(pptx_path: str):
workspace = Path(os.getcwd()).resolve()
target = Path(pptx_path).resolve()
if not target.is_relative_to(workspace):
raise ValueError(f"Access denied: path outside workspace: {target}")
target.parent.mkdir(parents=True, exist_ok=True)
self.empty_prs.save(str(target))
- Record
GHSA-pxhg-7xr2-w7xg- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-22
- Updated
- 2026-11-02
NVD
4.6
PPTAgent is an agentic framework for reflective PowerPoint generation. Prior to commit 418491a, there is an arbitrary file write vulnerability via save_generated_slides. This issue has been patched via commit 418491a.
- Record
CVE-2026-42080- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-22
- Updated
- 2026-11-02
OSV
4.6
PPTAgent: Arbitrary File Write via `save_generated_slides`
PPTAgent is an agentic framework for reflective PowerPoint generation. Prior to commit 418491a, there is an arbitrary file write vulnerability via save_generated_slides. This issue has been patched via commit 418491a.
- Record
CVE-2026-42080- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-22
- Updated
- 2026-11-02
OSVGHSA-pxhg-7xr2-w7xg
4.6
PPTAgent: Arbitrary File Write via `save_generated_slides`
Summary
This vulnerability has been fixed in https://github.com/icip-cas/PPTAgent/commit/418491a9a1c02d9d93194b5973bb58df35cf9d00.
The save_generated_slides MCP tool accepts a pptx_path argument and writes the generated PPTX file to that path without any workspace restriction or path validation:
# pptagent/mcp_server.py:288-300
async def save_generated_slides(pptx_path: str):
"""Save the generated slides to a PowerPoint file.
Args:
pptx_path: The path to save the PowerPoint file
"""
pptx = Path(pptx_path)
assert len(self.slides), (
"No slides generated, please call `generate_slide` first"
)
pptx.parent.mkdir(parents=True, exist_ok=True) # ← creates arbitrary directories
self.empty_prs.save(pptx_path) # ← writes to arbitrary path
The call to pptx.parent.mkdir(parents=True, exist_ok=True) creates any intermediate directories, and self.empty_prs.save(pptx_path) writes a valid PPTX binary (ZIP archive) to the specified path. No is_relative_to(workspace) check is performed — contrast with download_file in deeppresenter/tools/search.py:290, which correctly enforces workspace confinement.
The server changes directory to WORKSPACE (if set) on startup, so relative paths land in the workspace. Absolute paths, however, reach any filesystem location accessible to the server process.
Impact
The concrete attack scenarios include
- Cron persistence (root-running server):
pptx_path = "/etc/cron.d/backdoor"→ writes a PPTX ZIP to a path the cron daemon reads; if the ZIP header is misinterpreted, this may corrupt cron or be exploitable depending on parser behaviour. - Dot-file overwrite:
pptx_path = "/home/user/.bashrc"→ overwrites shell init file with a binary blob containing arbitrary content in the PPTX's embedded comments/custom properties. - Directory traversal from workspace:
pptx_path = "../../.ssh/known_hosts.pptx"→ escapes workspace entirely. - Denial of service:
pptx_path = "/dev/sda"writes to a raw device.
Remediation
The potential fix is something like:
async def save_generated_slides(pptx_path: str):
workspace = Path(os.getcwd()).resolve()
target = Path(pptx_path).resolve()
if not target.is_relative_to(workspace):
raise ValueError(f"Access denied: path outside workspace: {target}")
target.parent.mkdir(parents=True, exist_ok=True)
self.empty_prs.save(str(target))
- Record
GHSA-pxhg-7xr2-w7xg- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Weakness
- CWE-22
- Updated
- 2026-11-02
OSVPYSEC-2026-2894
4.6
PPTAgent: Arbitrary File Write via `save_generated_slides`
Summary
This vulnerability has been fixed in https://github.com/icip-cas/PPTAgent/commit/418491a9a1c02d9d93194b5973bb58df35cf9d00.
The save_generated_slides MCP tool accepts a pptx_path argument and writes the generated PPTX file to that path without any workspace restriction or path validation:
# pptagent/mcp_server.py:288-300
async def save_generated_slides(pptx_path: str):
"""Save the generated slides to a PowerPoint file.
Args:
pptx_path: The path to save the PowerPoint file
"""
pptx = Path(pptx_path)
assert len(self.slides), (
"No slides generated, please call `generate_slide` first"
)
pptx.parent.mkdir(parents=True, exist_ok=True) # ← creates arbitrary directories
self.empty_prs.save(pptx_path) # ← writes to arbitrary path
The call to pptx.parent.mkdir(parents=True, exist_ok=True) creates any intermediate directories, and self.empty_prs.save(pptx_path) writes a valid PPTX binary (ZIP archive) to the specified path. No is_relative_to(workspace) check is performed — contrast with download_file in deeppresenter/tools/search.py:290, which correctly enforces workspace confinement.
The server changes directory to WORKSPACE (if set) on startup, so relative paths land in the workspace. Absolute paths, however, reach any filesystem location accessible to the server process.
Impact
The concrete attack scenarios include
- Cron persistence (root-running server):
pptx_path = "/etc/cron.d/backdoor"→ writes a PPTX ZIP to a path the cron daemon reads; if the ZIP header is misinterpreted, this may corrupt cron or be exploitable depending on parser behaviour. - Dot-file overwrite:
pptx_path = "/home/user/.bashrc"→ overwrites shell init file with a binary blob containing arbitrary content in the PPTX's embedded comments/custom properties. - Directory traversal from workspace:
pptx_path = "../../.ssh/known_hosts.pptx"→ escapes workspace entirely. - Denial of service:
pptx_path = "/dev/sda"writes to a raw device.
Remediation
The potential fix is something like:
async def save_generated_slides(pptx_path: str):
workspace = Path(os.getcwd()).resolve()
target = Path(pptx_path).resolve()
if not target.is_relative_to(workspace):
raise ValueError(f"Access denied: path outside workspace: {target}")
target.parent.mkdir(parents=True, exist_ok=True)
self.empty_prs.save(str(target))
- Record
PYSEC-2026-2894- CVSS 3.1
- 4.6 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:L - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
pptagentPyPI |
before 1.1.36 | 1.1.36 |
pptagentPyPI |
before 1.1.36, plus listed versions 0.2.00.2.10.2.100.2.110.2.13 Show 45 moreShow less0.2.140.2.150.2.160.2.170.2.180.2.20.2.30.2.40.2.50.2.60.2.70.2.80.2.91.0.01.0.11.0.21.1.11.1.101.1.111.1.121.1.131.1.141.1.151.1.161.1.171.1.181.1.191.1.21.1.201.1.211.1.221.1.241.1.261.1.271.1.281.1.291.1.31.1.301.1.311.1.321.1.331.1.341.1.351.1.51.1.6 |
1.1.36 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-42080 is a medium vulnerability (CVSS 4.6) in Icip-cas Pptagent, published May 4, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.20%, the 9th percentile. Fixed in pptagent 1.1.36.
References
github.com/icip-cas/PPTAgent/security/advisories/GHSA-pxhg-7xr2-w7xg
github.com/icip-cas/PPTAgent/commit/418491a9a1c02d9d93194b5973bb58df35cf9d00
nvd.nist.gov/vuln/detail/CVE-2026-42080
github.com/advisories/GHSA-pxhg-7xr2-w7xg
github.com/CVEProject/cvelistV5/tree/main/cves/2026/42xxx/CVE-2026-42080.json
github.com/icip-cas/PPTAgent
pypi.org/project/pptagent
Left out here: 3 versions. The JSON record has them.