Description
Playlist names containing a forward slash (/) are passed to clean_filepath() without prior slash substitution, causing the OS to interpret them as path separators. This creates unintended subdirectories and, with a crafted name, could write files outside the intended download folder (path traversal).
Root cause
streamrip/filepath_utils.py defines two functions:
clean_filename(fn) — replaces / with - before sanitizing. Used for track filenames and album/artist components in format_folder_path.
clean_filepath(fn) — calls sanitize_filepath() which preserves / as a legitimate path separator. Used directly for playlist folder names.
In streamrip/media/playlist.py:
# line 176 — Deezer/Qobuz/Tidal playlists
folder = os.path.join(parent, clean_filepath(name))
# line 248 — last.fm playlists
folder = os.path.join(parent, clean_filepath(playlist_title))
Neither call goes through clean_filename first, so a playlist named Best of 80s/90s creates:
~/StreamripDownloads/Best of 80s/
└── 90s/
└── track.flac
A crafted name like ../../sensitive_dir could escape the download root entirely.
Albums are not affected
AlbumMetadata.format_folder_path() (streamrip/metadata/album.py:71,76) passes albumartist and title through clean_filename() before the template is expanded, so slashes in album/artist names are already replaced with -.
Fix
Replace / with - (or ∕ U+2215) in the playlist name before passing it to clean_filepath, or use clean_filename for the single-component case:
# playlist.py line 176
folder = os.path.join(parent, clean_filepath(clean_filename(name)))
# playlist.py line 248
folder = os.path.join(parent, clean_filepath(clean_filename(playlist_title)))
Description
Playlist names containing a forward slash (
/) are passed toclean_filepath()without prior slash substitution, causing the OS to interpret them as path separators. This creates unintended subdirectories and, with a crafted name, could write files outside the intended download folder (path traversal).Root cause
streamrip/filepath_utils.pydefines two functions:clean_filename(fn)— replaces/with-before sanitizing. Used for track filenames and album/artist components informat_folder_path.clean_filepath(fn)— callssanitize_filepath()which preserves/as a legitimate path separator. Used directly for playlist folder names.In
streamrip/media/playlist.py:Neither call goes through
clean_filenamefirst, so a playlist namedBest of 80s/90screates:A crafted name like
../../sensitive_dircould escape the download root entirely.Albums are not affected
AlbumMetadata.format_folder_path()(streamrip/metadata/album.py:71,76) passesalbumartistandtitlethroughclean_filename()before the template is expanded, so slashes in album/artist names are already replaced with-.Fix
Replace
/with-(or∕U+2215) in the playlist name before passing it toclean_filepath, or useclean_filenamefor the single-component case: