[GH-ISSUE #360] credentials.json is world-readable #238

Closed
opened 2026-02-27 19:29:35 +03:00 by kerem · 2 comments
Owner

Originally created by @sigvei on GitHub (Aug 7, 2019).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/360

Librespot caches credentials in $cache/credentials.json. On my system (Arch Linux; using Librespot through spotifyd) the file seems to be created world- and group-readable (644).

The file stores an authentication token, not the password, so I guess this is not a very serious security issue. It should probably at least be mentioned in the docs that the cache dir should be kept secure (700). As it stands, users might (sensibly!) assign /tmp as a cache dir, which would expose the token to all users on the system.

Originally created by @sigvei on GitHub (Aug 7, 2019). Original GitHub issue: https://github.com/librespot-org/librespot/issues/360 Librespot caches credentials in `$cache/credentials.json`. On my system (Arch Linux; using Librespot through spotifyd) the file seems to be created world- and group-readable (644). The file stores an authentication token, not the password, so I guess this is not a very serious security issue. It should probably at least be mentioned in the docs that the cache dir should be kept secure (700). As it stands, users might (sensibly!) assign /tmp as a cache dir, which would expose the token to all users on the system.
kerem closed this issue 2026-02-27 19:29:35 +03:00
Author
Owner

@cip123 commented on GitHub (Mar 22, 2020):

I would like to start working on this one but I am completely new to Rust so I would like to ask somebody opinion on the implementation.

I took a quick look at the code and the main problem that I see is the portability between Windows and Unix.

i.e I could do something like this in authentication.rs

        use std::os::unix::fs::OpenOptionsExt;

        let mut options = OpenOptions::new();
        options.write(true).create(true).truncate(true);
        
        if cfg!(unix) {
            options.mode(0o600);
        }
        
        let mut file = options.open(path.as_ref()).unwrap();
        self.save_to_writer(&mut file)

but the tricky part would be to conditionally compile std::os::unix::fs::OpenOptionsEx.
My first thought is to separate the logic into different files with a trait or an interface and then load that specific file conditionally with #[cfg(target_os = "<unix|windows>")]

<!-- gh-comment-id:602200065 --> @cip123 commented on GitHub (Mar 22, 2020): I would like to start working on this one but I am completely new to Rust so I would like to ask somebody opinion on the implementation. I took a quick look at the code and the main problem that I see is the portability between Windows and Unix. i.e I could do something like this in `authentication.rs` ``` use std::os::unix::fs::OpenOptionsExt; let mut options = OpenOptions::new(); options.write(true).create(true).truncate(true); if cfg!(unix) { options.mode(0o600); } let mut file = options.open(path.as_ref()).unwrap(); self.save_to_writer(&mut file) ``` but the tricky part would be to conditionally compile `std::os::unix::fs::OpenOptionsEx`. My first thought is to separate the logic into different files with a trait or an interface and then load that specific file conditionally with `#[cfg(target_os = "<unix|windows>")]`
Author
Owner

@sashahilton00 commented on GitHub (Jan 31, 2021):

Added a note in the README.md

<!-- gh-comment-id:770314755 --> @sashahilton00 commented on GitHub (Jan 31, 2021): Added a note in the `README.md`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/librespot#238
No description provided.