From 97b0a6e7f15cb094d4d2e87ef000e3579489a60c Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 20 May 2026 14:11:35 +0300 Subject: Validate AbsPath in streamer and clean up partial podcast downloads (l9+k9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit l9: Add mediaRoot field to mediaStreamer. NewMediaStreamer now takes a mediaRoot string parameter; when non-empty, Open() rejects any path that does not reside under that directory (filepath.Clean prefix check), returning ErrForbidden to prevent filepath-traversal via a compromised AbsPath in the DB. Production wiring passes cfg.MediaRoot; tests that don't exercise path traversal pass "". Added TestMediaStreamerOpenRejectsPathOutsideRoot to cover the rejection path. k9: Add a defer-based cleanup guard in DownloadEpisode. After the enclosure file is written, a succeeded flag gates a deferred closure that calls dbCleanup() (undoes DB row + removes file) when persistDownloadedEpisode succeeded, or removeAndLog(path) when it did not. This ensures that any failure after the file is written — including UpdateEpisodeMedia — leaves no orphaned files on disk. The guard is disarmed by setting succeeded=true on the happy path. Co-Authored-By: Claude Opus 4.7 --- player-server/cmd/player/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'player-server/cmd') diff --git a/player-server/cmd/player/main.go b/player-server/cmd/player/main.go index 3e8046f..d69f3a9 100644 --- a/player-server/cmd/player/main.go +++ b/player-server/cmd/player/main.go @@ -253,7 +253,7 @@ func runWithSignal(args []string, sigCh <-chan os.Signal) error { staticFS := http.Dir("web") remuxer := probe.NewFFRemuxer() - streamer := service.NewMediaStreamer(remuxer) + streamer := service.NewMediaStreamer(remuxer, cfg.MediaRoot) server, err := api.NewServerWithLogger(api.ServerDeps{ Store: store, Hasher: deps.hasher, -- cgit v1.2.3