CVE-2026-45242
Description
Summarize prior to 0.15.1 contains a path traversal vulnerability in the /v1/summarize daemon endpoint that allows authenticated callers to write files to arbitrary directories by supplying an absolute path or directory traversal sequence in the slidesDir request parameter. Attackers can exploit this to write slide_*.png and slides.json files to any writable directory and subsequently delete matching files at the specified location through repeat extraction.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Authenticated callers can exploit a path traversal in Summarize's daemon to write and delete slide files outside the intended directory.
Vulnerability
Summarize prior to version 0.15.1 contains a path traversal vulnerability in the /v1/summarize daemon endpoint. The slidesDir request parameter was passed directly to path.resolve() without sanitization, allowing absolute paths or .. traversal sequences to redirect file operations outside the intended ~/.summarize/slides directory [1][2].
Exploitation
An authenticated attacker can supply an absolute path or directory traversal sequence in the slidesDir parameter. The daemon, which runs with the user's filesystem privileges, then writes generated slide_*.png and slides.json files to the attacker-controlled directory. On repeat extraction, the cleanup logic deletes matching files at that location, enabling both arbitrary file write and deletion [1][4].
Impact
Successful exploitation allows an authenticated caller to write slide artifacts to any writable directory on the host filesystem and delete existing files matching the slide_*.png or slides.json patterns. This can lead to data corruption, denial of service, or potentially further compromise depending on the writable target [1][4].
Mitigation
The vulnerability is fixed in Summarize version 0.15.2, released on 2026-05-17 [3]. The fix ignores the request-supplied slidesDir value and always writes slide artifacts under ~/.summarize/slides [1][2]. Users should upgrade to version 0.15.2 or later.
- [security] fix(daemon): keep slide output under user directory by Hinotoi-agent · Pull Request #220 · steipete/summarize
- [security] fix(daemon): keep slide output under user directory (#220) · steipete/summarize@ec8efd6
- Release v0.15.2 · steipete/summarize
- Summarize < 0.15.1 Path Traversal via slidesDir Parameter
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
1ec8efd632956[security] fix(daemon): keep slide output under user directory (#220)
3 files changed · +74 −1
CHANGELOG.md+1 −0 modified@@ -8,6 +8,7 @@ ### Fixes +- Daemon slides: ignore request-provided slide output directories and keep extracted slide artifacts under `~/.summarize/slides` (#220, thanks @Hinotoi-agent). - CLI progress: keep Ctrl+C responsive while spinners are active and forward interrupts to active CLI model backends so child processes are not left running (#216). - Codex CLI: isolate normal summary runs with `--ephemeral`, `--ignore-user-config`, `--ignore-rules`, a temporary cwd, and a sanitized temporary `CODEX_HOME` so local Codex context cannot bleed into summaries with little or no extracted content (#215, thanks @anntnzrb). - Daemon: write `~/.summarize/daemon.json` with owner-only permissions and tighten existing config paths before rewriting daemon tokens or captured provider env values (#214, thanks @Hinotoi-agent).
src/daemon/server-summarize-request.ts+5 −1 modified@@ -38,7 +38,11 @@ function resolveRequestSlidesSettings({ return resolveSlideSettings({ slides: slidesValue, slidesOcr: slidesOcrValue, - slidesDir: request.slidesDir ?? ".summarize/slides", + // Daemon/API callers may be browser-extension or localhost clients that + // only need to request extraction, not select host filesystem paths. Keep + // slide artifacts under the per-user Summarize directory so an authenticated + // request cannot write/delete slide files in arbitrary writable locations. + slidesDir: ".summarize/slides", slidesSceneThreshold: request.slidesSceneThreshold, slidesSceneThresholdExplicit: typeof request.slidesSceneThreshold !== "undefined", slidesMax: request.slidesMax,
tests/daemon.request-slides-settings.test.ts+68 −0 added@@ -0,0 +1,68 @@ +import type http from "node:http"; +import { Readable } from "node:stream"; +import { describe, expect, it, vi } from "vitest"; +import { parseSummarizeRequest } from "../src/daemon/server-summarize-request.js"; + +function createJsonRequest(body: unknown): http.IncomingMessage { + const req = Readable.from([JSON.stringify(body)]) as http.IncomingMessage; + req.headers = {}; + return req; +} + +function createResponse(): http.ServerResponse { + return { + writeHead: vi.fn(), + end: vi.fn(), + } as unknown as http.ServerResponse; +} + +const resolveToolPath = (binary: string) => (binary === "tesseract" ? "/usr/bin/tesseract" : null); + +describe("parseSummarizeRequest slides settings", () => { + it("keeps daemon-requested slide output under the user Summarize directory", async () => { + for (const slidesDir of ["/tmp/attacker-slides", "../../attacker-slides", "nested/slides"]) { + const parsed = await parseSummarizeRequest({ + req: createJsonRequest({ + url: "https://example.com/video.mp4", + mode: "url", + slides: true, + slidesDir, + }), + res: createResponse(), + cors: {}, + env: { HOME: "/home/alice" }, + resolveToolPath, + }); + + expect(parsed).not.toBeNull(); + expect(parsed?.slidesSettings?.outputDir).toBe("/home/alice/.summarize/slides"); + } + }); + + it("still honors non-path slide options from daemon requests", async () => { + const parsed = await parseSummarizeRequest({ + req: createJsonRequest({ + url: "https://example.com/video.mp4", + mode: "url", + slides: true, + slidesOcr: true, + slidesMax: 3, + slidesMinDuration: 4, + slidesSceneThreshold: 0.5, + }), + res: createResponse(), + cors: {}, + env: { HOME: "/home/alice" }, + resolveToolPath, + }); + + expect(parsed?.slidesSettings).toMatchObject({ + enabled: true, + ocr: true, + outputDir: "/home/alice/.summarize/slides", + maxSlides: 3, + minDurationSeconds: 4, + sceneThreshold: 0.5, + }); + }); +});
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
4- github.com/steipete/summarize/commit/ec8efd63295656fbfe8743620179c489bc5a242fnvdPatch
- github.com/steipete/summarize/pull/220nvdExploitIssue TrackingPatch
- www.vulncheck.com/advisories/summarize-path-traversal-via-slidesdir-parameternvdThird Party Advisory
- github.com/steipete/summarize/releases/tag/v0.15.2nvdRelease Notes
News mentions
12- Breaking the Black Box: A Case Study in Red-Teaming a Government Education AISentinelOne Labs · May 18, 2026
- New Windows 'MiniPlasma' zero-day exploit gives SYSTEM access, PoC releasedBleepingComputer · May 17, 2026
- Securing data centers in the agentic AI eraTenable Blog · May 13, 2026
- Your Purple Team Isn't Purple — It's Just Red and Blue in the Same RoomThe Hacker News · May 11, 2026
- Security teams are turning to AI to survive alert overloadHelp Net Security · May 11, 2026
- Websites with an undefined trust level: avoiding the trapSecurelist · May 6, 2026
- Mastering agentic AI security through exposure managementTenable Blog · Apr 29, 2026
- Researchers Uncover 10 In-the-Wild Prompt Injection Payloads Targeting AI AgentsInfosecurity Magazine · Apr 23, 2026
- Moving past bots vs. humansCloudflare Blog · Apr 21, 2026
- Project Glasswing and the Next Challenge for Defenders: Turning Faster Discovery into Faster ActionRapid7 Blog · Apr 20, 2026
- Fracturing Software Security With Frontier AI ModelsUnit 42 · Apr 20, 2026
- Falcon AIDR Detects Threats at the Prompt Layer in Kubernetes AI ApplicationsCrowdStrike Blog