Skip to content

Path traversal: playlist names containing '/' create unintended subdirectories #3

Description

@berettavexee

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)))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions