Shady behaviour by Spotify desktop client observed with Wireshark. Expertise appreciated!

Hello Level1 friends,

I installed and fired up Wireshark earlier for reasons unrelated to this post, and while glancing over the unfiltered traffic looking for my application I noticed something else which surprised me.

As soon as the desktop Spotify client is opened (Windows), Wireshark sees loads of requests for files at several SMB servers of mine. These requests stop as soon as Spotify is killed. Weirdly, it looks at both 192.168.1.118 (a SMB server on my Plex VM that I no longer use and is not mapped in Windows) and 192.168.1.236 (my primary storage server which is mapped in Windows). I have attached a couple of Wireshark screenshots and a 30 second pcap wherein I began capturing, Spotify is opened, I waited 30 seconds, then stopped capturing.

I am aware that Spotify has some features where you can save files to disk for use offline (I do not use this feature and have never pointed it at any network locations), and also that it can be used to play locally stored media that is not available from the Spotify library (similarly, I have never used this feature and have not pointed it at any network locations).

As I am not very familiar with packet sniffing or network protocol behaviour in general, I was hoping someone could help me work out why Spotify seems to be hitting network shares (including ones not even mapped/mounted in Windows) when it (as far as I can imagine) has no business doing so?

I have also included a screenshot of the storage-related options in Spotify, showing it only using AppData for caching and not any samba shares.

Thanks for reading,

Jake



3 Likes

I don’t know why this piece of software behaves like that, I don’t use it personally, so it’s hard for me to comment on it.

Certainly, such behavior would be extremely unpleasant for me as well.

One thing I can recommend as a golden rule is firewall per device and filter per process.

Comodo Firewall… It will give you full control of this process and where to connect. You can quickly block access to LAN resources.

The HIPS function can additionally introduce some restrictions on what such a process can touch on the disk.

And to complete the whole thing, you can run this process in a sandbox.

5 Likes

Thanks for the advice, I have taken a few mitigation measures now. I’m still pretty curious about what it was doing in the first place, and how it knew to go looking for SMB servers that weren’t even mapped in Windows File Explorer. Presumably it was able to find a record of the hostname and credentials from a cache or log somewhere? Very disconcerting imo, I’d love if someone could provide some kind of “it’s not as evil as it seems” explaination!

2 Likes
  • Make sure the application is from an official source and it’s not a fake.
  • Scan your entire system with Malwarebytes.
  • Upload the installed files to virustotal.

How could the application know anything?.. all it needs to do is scan the lan address and look for an open smb.
If uses other methods to obtain information by searching the OS, I automatically consider such a thing to be malware, even if it is an official app.

As I mentioned before… firewall, firewall and firewall :wink:
For me, no process will make a successful network connection without my knowledge.
I always know which process, where and when is trying to connect and I decide whether to allow it, so you would see immediately from the first moment that something is happening. :wink:

2 Likes

it looks to be looking in music and pictures for files you already have so it doesnt have to download.
but thats a guess from 1 screen of info.

try tracing some of the requests for get.
set your desktop to show all hidden files. then when you see desktop ini.
open it with notepad…
it will likely contain a list of files spotify is looking for…
then go look them up in your pcap if you feel you need to.

1 Like

Hi,

It is an interesting find and I always get curious when seeing Pcap’s. :slight_smile:

Are you sure it’s the Spotify process doing this and not something else on the computer?
It sounds like it is Spotify from your description… but just to be sure you could check in Sysinternals Process Monitor - it will show you the process ID’s for network traffic.

This got me curious on the behavior of Spotify on my own Windows machine.

I fired up Process Monitor and can confirm that Spotify scans my local music folder (Music in the home folder), but I don’t see any network scans. I don’t have any SMB server on the same subnet though.
Spotify has a “Show Local Files” feature in Preferences / Library, I’m guessing this has something to do with the scanning. I have it turned off - but Spotify is still scanning my local files. :frowning:

As was mentioned here above, I would look at/configure a firewall/HIPS to get better visibility if you want to. If you are working with Windows machines you can even block some of this in the built-in Windows Firewall (wf.msc console).

By default most Windows machines (and some NAS) will broadcast their existence on the local network - so it will not be hard for an application to locate the SMB shares (the application might not even have to do a network scan).

I come from the networking world, and I would put my client machines on one subnet and servers on another subnet… but that’s probably another topic/discussion. :slight_smile:

//Erik

1 Like

Hi Erik. Thanks for taking the time to examine the client behaviour on your system, the indescriminate scanning of local media does seem like pretty bad behaviour to me - how interesting. I’ll check things out in more detail using Process Monitor after work.

~~

Alright, while this was still a draft curiousity got the better of me at work. Procmon shows Spotify scanning all kinds of funny places. Gmail takeout in my Downloads folder:

The assorted network locations from before (including 192.168.1.118 whose SMB server is now disabled):

image

as well as C:/Users/Public/Music, C:/Users/Jake/Music etc. I’m not particularly delighted by this discovery if I’m honest :sweat_smile:

I’ll get back to work now but will probably continue checking this out later on, I’m officially intrigued.

4 Likes

I don’t have either windows nor spotify, but my first guess about the smb share is that you have some sort of discovery enabled on those, and it use some zeroConf DNS thing to liste all network share.

If spotify have a way to play local file, it would make sense for it to scan the computer and network device for such.
Also i think i remember from a home assistant OS release that it can broadcast it’s music to airplay or DNLA client… so this could do some network scanning as well

2 Likes

Spotify does seem to have some facility for playing local files, but I have never had it toggled on :confused:
image

not showing don’t mean not scanning :crazy_face:
Question is, what’s on their privacy policy, that’s where the good stuff is :slight_smile:

2 Likes

I haven’t yet managed to grab a desktop.ini as presumably they are created and cleaned up fairly quickly. I’ll spend a bit more effort later and recover/examine one :slight_smile:

A good method would also be not to keep data in typical locations. I always create separate dedicated private directories and absolutely avoid keeping them in a typical data location. What is more important, I also keep the data in the veracrypt container, which is encrypted whenever there is no need to access the content. In this way, the scope of snooping is limited by nosy applications, but not completely eliminated. For this purpose, you need to strongly limit applications with even hips.

The behavior may also be dictated by the fact that the application is searching/trying to import everything that is in the specified location.

And this behavior is nothing new as you can see…
https://www.reddit.com/r/truespotify/comments/pcdvaf/just_noticed_heavy_disk_usage_and_found_spotify/

If you still plan to use this application, then all you have to do is to block network traffic for the process towards smb servers.
And sensitive local locations will be limited with hips then they will just be empty for the application.

By the way, the telemetry that goes to the mother ship is probably interesting… :wink:

2 Likes

In combination with the shady traffic found in this thread, I also came across another unfortunate thread:

Very not impressed with this “Premium” service. Of course I give no microphone permissions on a degoogled GrapheneOS, but its still insulting to pay to be spied on.

I wonder if they try to scan files on android like they do desktop? Luckily file Discretionary Access Control (DAC) sandboxing has become a thing to mitigate this. Application Sandbox  |  Android Open Source Project

In adb there are the failed attempts to load GMS ads identifier:


And a failed attempt to read my serial identifier via TelephonyPermissions:


So despite having paid for premium to remove ads, but they still add ads to some podcasts. That’s double dipping.

Unfortunately the ads come through the same severs as the music so they aren’t filtered out by the pihole, very irritating:

https://open.spotify.com/ad/%s

Why am I paying to listen to ads? This is not acceptable.


So I did a little digging with the attempt to try and get rid of those ads by perhaps patching out the call. Ban me spotfiy I dont care, I refuse to pay to listen to ads.

In the process I found a concerning string: s_voice_ad_inaudible_tone_enabled

My note’s are a little old but here we go. The sample used was the snap package version.

The process path said
/snap/spotify/56/usr/share/spotify/spotify

I couldn’t find that path. Turns out snaps are mounted with their own virtual filesystem, and the actual .snap stored in
/var/lib/snapd/
Source: Managing Ubuntu Snaps: the stuff no one tells you | HackerNoon

I found spotify binary in
/var/lib/snapd/snaps/spotify_56.snap

Unzipping didnt work. To get into the snap, I had to mount with squashfs and dump the contents to a directory
sudo mount -t squashfs -o ro /var/lib/snapd/snaps/spotify_56.snap /path/to/extract/spotify
Source: How do I view the contents of a .snap file? - Ask Ubuntu

Now, digging through the extracted files (and following the path our original process was running) we find the actual binary in
<extractedPath>/usr/share/spotify/spotify

Open the binary in Ghidra. Once analyzed: Search > For Strings…
Filter for ‘ad’, sorted alphabetically by ‘String View’.

And right away we find some interesting enteries:
	002a262d		?? 2Fh    /	"/v1/ads/:slot"	string	14	false
	002c3b54		?? 2Fh    /	"/v1/events/:event/:ad_id"	string	25	true
	002abb2f	DAT_002abb2f	?? 2Fh    /	"/v1/playlist/:playlist-uri/metadata"	string	36	true
	002956ea		?? 2Fh    /	"/v1/podcast/metadata"	string	21	true
	002d7356		?? 2Fh    /	"/v1/podcast/nextAdSegment"	string	26	true
	002d72ed		?? 2Fh    /	"/v1/preview/:ad_id"	string	19	true
	002c1371		?? 2Fh    /	"/v1/settings/:slot/ad_server_endpoint"	string	38	true
	0028c28b		?? 2Fh    /	"/v1/settings/request_header/:header"	string	36	true
	002ba844		?? 2Fh    /	"/v1/testing/click_ad"	string	21	true
	00299a1f	DAT_00299a1f	?? 2Fh    /	"/v2/metadata"	string	13	true
	002d3e17		?? 2Fh    /	"/v2/settings/ad_server_endpoint"	string	32	true
	002bd001		?? 2Fh    /	"/v2/settings/state/ad_state_endpoint"	string	37	true
	002c586b		?? 2Fh    /	"/v2/testing/insert_ads"	string	23	true
	
Some more:
	0028e53e	s_active_ads_0028e53e	ds "active_ads"	"active_ads"	string	11	true
	002c151b	s_ad_fetch_error_(_002c151b	ds "ad fetch error ("	"ad fetch error ("	string	17	true
	00290fce	s_Ad_format_(_00290fce	ds "Ad format ("	"Ad format ("	string	12	true
	002957e6	s_ad_missing_id_002957e6	ds "ad missing id"	"ad missing id"	string	14	true
	002d9391	s_Ad_not_found_for_provided_ad_id_002d9391	ds "Ad not found for provided ad_id"	"Ad not found for provided ad_id"	string	32	true
	002a27d5	s_ad_parse_error_-_002a27d5	ds "ad parse error - "	"ad parse error - "	string	18	true
	002a6f22	s_ad_response_error_(_002a6f22	ds "ad response error ("	"ad response error ("	string	20	true
	0029796f	s_ad-logic/flashpoint_0029796f	ds "ad-logic/flashpoint"	"ad-logic/flashpoint"	string	20	true
	002c80ee	s_ad-logic/state/config_002c80ee	ds "ad-logic/state/config"	"ad-logic/state/config"	string	22	true
	002cc6d9	s_ad-session-persistence_002cc6d9	ds "ad-session-persistence"	"ad-session-persistence"	string	23	true
	00299ca3	s_ad-state-storage.bnk_00299ca3	ds "ad-state-storage.bnk"	"ad-state-storage.bnk"	string	21	true
	002b88e5	s_ad-use-adlogic_002b88e5	ds "ad-use-adlogic"	"ad-use-adlogic"	string	15	true
	002a6f10	s_ad.is_saved_track_002a6f10	ds "ad.is_saved_track"	"ad.is_saved_track"	string	18	true
	00295818	s_ad.non_explicit_00295818	ds "ad.non_explicit"	"ad.non_explicit"	string	16	true
	002d3ff2	s_ad.original_provider_002d3ff2	ds "ad.original_provider"	"ad.original_provider"	string	21	true
	002bf4fc	s_ad.token_002bf4fc	ds "ad.token"	"ad.token"	string	9	true
	0029344c	s_ad.video_orientation_0029344c	ds "ad.video_orientation"	"ad.video_orientation"	string	21	true
	002c147b	s_ad_break_in_progress_002c147b	ds "ad_break_in_progress"	"ad_break_in_progress"	string	21	true
	002dc2e4	s_ad_break_state_002dc2e4	ds "ad_break_state"	"ad_break_state"	string	15	true
	002c80ce	s_ad_break_time_002c80ce	ds "ad_break_time"	"ad_break_time"	string	14	true
	0034abb0	s_ad_core_sponsored_session_0034abb0	ds "ad_core_sponsored_session"	"ad_core_sponsored_session"	string	26	true
	002b091b	s_ad_disallow_002b091b	ds "ad_disallow"	"ad_disallow"	string	12	true
	002c58b2	s_ad_enabled_002c58b2	ds "ad_enabled"	"ad_enabled"	string	11	true
	002a6d5b	s_ad_id_002a6d5b	ds "ad_id"	"ad_id"	string	6	false
	0029df74	s_ad_injection_seek_0029df74	ds "ad_injection_seek"	"ad_injection_seek"	string	18	true
	002abe4e	s_ad_manager_002abe4e	ds "ad_manager"	"ad_manager"	string	11	true
	002957c9	s_ad_not_sponsored_by_rewarder_002957c9	ds "ad_not_sponsored_by_rewarder"	"ad_not_sponsored_by_rewarder"	string	29	true
	0028e3ff	s_ad_playback_0028e3ff	ds "ad_playback"	"ad_playback"	string	12	true
	002bd05a	s_ad_playback_id_002bd05a	ds "ad_playback_id"	"ad_playback_id"	string	15	true
	002c1490	s_ad_rule_disallows_002c1490	ds "ad_rule_disallows"	"ad_rule_disallows"	string	18	true
	002a4555	s_ad_server_endpoint_002a4555	ds "ad_server_endpoint"	"ad_server_endpoint"	string	19	true
	002d93c8	s_ad_slot_id_002d93c8	ds "ad_slot_id"	"ad_slot_id"	string	11	true
	002b892f	s_ad_state_pusher_error:_%s_002b892f	ds "ad_state_pusher error: %s"	"ad_state_pusher error: %s"	string	26	true
	002bd052	s_ad_type_002bd052	ds "ad_type"	"ad_type"	string	8	true
	
And some more:
	0034ab80	s_core-ads_0034ab80	ds "core-ads"	"core-ads"	string	9	true
	0034aba3	s_core-ads_0034aba3	ds "core-ads"	"core-ads"	string	9	true
	0034abcb	s_core-ads_0034abcb	ds "core-ads"	"core-ads"	string	9	true
	0034ac30	s_core-ads_0034ac30	ds "core-ads"	"core-ads"	string	9	true	
	00290fe9	s_core-podcast-ad-requester_00290fe9	ds "core-podcast-ad-requester"	"core-podcast-ad-requester"	string	26	true
	00337130	s_core-podcast-ads_00337130	ds "core-podcast-ads"	"core-podcast-ads"	string	17	true
	00337180	s_core-podcast-ads_00337180	ds "core-podcast-ads"	"core-podcast-ads"	string	17	true
	003350d0	s_core-podcast-ads-feature_003350d0	ds "core-podcast-ads-feature"	"core-podcast-ads-feature"	string	25	true
	00335120	s_core-podcast-ads-feature_00335120	ds "core-podcast-ads-feature"	"core-podcast-ads-feature"	string	25	true
	002ceabd	s_core-proxy-ad-requester_002ceabd	ds "core-proxy-ad-requester"	"core-proxy-ad-requester"	string	24	true
	00334178	s_core-voice-ad_00334178	ds "core-voice-ad"	"core-voice-ad"	string	14	true
	
Ooh! An advertisement URL -> https://open.spotify.com/ad/%s
	002a1d1a	s_https://open.spotify.com/ad/%s_002a1d1a	ds "https://open.spotify.com/ad/%s"	"https://open.spotify.com/ad/%s"	string	31	true	
	
And of course more:
	002dd036	s_injected-ad_002dd036	ds "injected-ad"	"injected-ad"	string	12	true	
	0029dfdc	s_invalid_ad_error__0029dfdc	ds "invalid_ad_error_"	"invalid_ad_error_"	string	18	true
	002c4ce8	s_invalid_download_error__002c4ce8	ds "invalid_download_error_"	"invalid_download_error_"	string	24	true
	0029f1e8	s_is_advertisement_0029f1e8	ds "is_advertisement"	"is_advertisement"	string	17	true
	002b642c	s_is_cpcl_ad_002b642c	ds "is_cpcl_ad"	"is_cpcl_ad"	string	11	true
	0029d0cc	s_is_podcast_advertisement_0029d0cc	ds "is_podcast_advertisement"	"is_podcast_advertisement"	string	25	true
	00383e60	s_isAvailableInMetadataCatalogue_00383e60	ds "isAvailableInMetadataCatalogue"	"isAvailableInMetadataCatalogue"	string	31	true
	00354ff7	s_isLoading_00354ff7	ds "isLoading"	"isLoading"	string	10	true
	00326080	s_isLoadingContents_00326080	ds "isLoadingContents"	"isLoadingContents"	string	18	true
	002abad0	s_isPremiumOnly_002abad0	ds "isPremiumOnly"	"isPremiumOnly"	string	14	true
	002cead5	s_skippable_ad_delay_002cead5	ds "skippable_ad_delay"	"skippable_ad_delay"	string	19	true
	002b3f8e	s_spotify:ad:_002b3f8e	ds "spotify:ad:"	"spotify:ad:"	string	12	true
	00290693	s_spotify:ad:%s_00290693	ds "spotify:ad:%s"	"spotify:ad:%s"	string	14	true
	002ba87b	s_test_ad_002ba87b	ds "test_ad"	"test_ad"	string	8	true
	0028c2af	s_The_ad_slot_could_not_be_trigger_0028c2af	ds "The ad slot could not be triggered"	"The ad slot could not be triggered"	string	35	true
	002ce91c	s_The_ad_slot_has_not_been_created_002ce91c	ds "The ad slot has not been created yet"	"The ad slot has not been created yet"	string	37	true
	002bd10d	s_too_many_redirect_ads_002bd10d	ds "too_many_redirect_ads"	"too_many_redirect_ads"	string	22	true
	002c811c	s_TriggerAdNotSuccessEvent_002c811c	ds "TriggerAdNotSuccessEvent"	"TriggerAdNotSuccessEvent"	string	25	true
	002bd172	s_TriggerAdSuccessEvent_002bd172	ds "TriggerAdSuccessEvent"	"TriggerAdSuccessEvent"	string	22	true
	0028e51d	s_triggered_ad_duration_0028e51d	ds "triggered_ad_duration"	"triggered_ad_duration"	string	22	true
	002b40a5	s_triggered_dummy_ad_duration_002b40a5	ds "triggered_dummy_ad_duration"	"triggered_dummy_ad_duration"	string	28	true
	00295837	s_UpdatePendingAd_NextContext_00295837	ds "UpdatePendingAd_NextContext"	"UpdatePendingAd_NextContext"	string	28	true
	002a6f36	s_UpdatePendingAd_Stream_002a6f36	ds "UpdatePendingAd_Stream"	"UpdatePendingAd_Stream"	string	23	true
	002af8ec	s_UpdatePendingAdEvent_002af8ec	ds "UpdatePendingAdEvent"	"UpdatePendingAdEvent"	string	21	true
	
Hmm, another URI? This looks like a callback redirect URI
	002cc5b9	s_Usage:_GET_sp://ads/v1/ads/<slot_002cc5b9	ds "Usage: GET sp://ads/v1/ads/<slot>"	"Usage: GET sp://ads/v1/ads/<slot>"	string	34	true
	
Oh, you thought that was it for ad related strings...
	00337150	s_use_new_podcast_ad_segments_prov_00337150	ds "use_new_podcast_ad_segments_provider"	"use_new_podcast_ad_segments_provider"	string	37	true
	002af805	s_useAdvertiserImage_002af805	ds "useAdvertiserImage"	"useAdvertiserImage"	string	19	true
	0029cad1	s_user_space_0029cad1	ds "user space"	"user space"	string	11	true
	002caadc	s_Users_002caadc	ds "Users"	"Users"	string	6	true
	002cc185	s_video/ad_002cc185	ds "video/ad"	"video/ad"	string	9	true
	002b6492	s_VND.Spotify.Ads-Payload_002b6492	ds "VND.Spotify.Ads-Payload"	"VND.Spotify.Ads-Payload"	string	24	true
	002ca2bc	s_voice_ad_002ca2bc	ds "voice_ad"	"voice_ad"	string	9	true
	002920ac	s_voice_ad_audio_sink_002920ac	ds "voice_ad_audio_sink"	"voice_ad_audio_sink"	string	20	true
	00293151	s_VoiceAdBuilder_00293151	ds "VoiceAdBuilder"	"VoiceAdBuilder"	string	15	true
	002af483	s_VoiceAdCosmosBuilder_002af483	ds "VoiceAdCosmosBuilder"	"VoiceAdCosmosBuilder"	string	21	true

Now this string is particularly interesting and mildly concerning:

	00334190	s_voice_ad_inaudible_tone_enabled_00334190	ds "voice_ad_inaudible_tone_enabled"	"voice_ad_inaudible_tone_enabled"	string	32	true

An inaudible tone huh?!

I highly suspect this to be an Ultrasonic Beacon:

Ultrasonic beacons are sounds with frequencies from 18 kHz to 20 kHz. Humans can’t hear it, but most mobile devices’ microphones can easily detect the ultrasonic beacons. When emitting from retail stores or embedded to advertisements and even websites, these inaudible sounds are picked up by microphones of mobile devices.

I have not confirmed this.

When I find the time I might revisit this. I’d like to maybe set up some sort of test with a microphone to confirm. Techniques for detecting this are described here: https://www.sec.cs.tu-bs.de/pubs/2017a-eurosp.pdf

6 Likes

So between all this nonsense, I will be cancelling my Spotify:

  1. shady traffic
  2. shady file scanning
  3. shady microphone patent to infer emotional state, age, gender, and accent
  4. shady inaudible tone → likely an Ultrasonic Beacon (unconfirmed)
  5. ads on podcasts while paying for premium to get rid of ads

Not cool spotify.

Besides, I’d rather pay artists more directly than pay spotify who gives fractions of pennies to artists:


I like Bandcamp, but Epic bought it in 2022. Epic employs dark-patterns in their games: The ‘dark patterns’ used by Epic Games that led to the largest ever FTC penalty - MarketWatch
And a certain large untrustworthy entity has a ~40% share in Epic. So I don’t want to support them either.
edit: Epic sold to Songtradr

Alternatives:

1 Like

I think they unbought it recently.

Not sure who owns it now though.

A company named SongTrader bought it from Epic for an undisclosed amount. No idea yet if this is a suspicious company.


Ever since the the release of the ultrasonic tone and other shady stuff like listening from the mic of your cellphone, I’ve stopped subbing to Music streaming services.

2 Likes

oh. well that’s better at least!

Bandcamp pays artists 82 percent of every transaction, while Spotify is widely reported to pay a small fraction of a cent per stream.

2 Likes

not much showing up in google.
but i found this…

turns out voice_ad_inaudible_tone_enabled might be a mitigation against a mytre attack
the other stuff looks to be to do with drm.

il load up wireshark myself in a bit and have a look at my free account… il let you know if i find similar… (i shouldnt if they are premium features)

3 Likes

I also want to dig deeper into refInaudibleTone.

will follow xrefs and report any findings when/if I find the time.

2 Likes

nope you were rite it is there ad platform not a mitigation.
seems Spotify has tiers for which you get ads even with premium.
seems you can watch/listen to some artists in premium and get ads by design.
but if you buy there video/album there is a drm check and it stops the ad playing.

yeah its double dipping but no different to buying espn then having to pay to watch a boxing match ppv.

and yes IT SUX!

3 Likes

also, is there a way to block specific directories on a domain at the router level? the pihole can only filter the DNS as far as I understand.

would an OpenWrt or DD-WRT type setup be able to provide more advanced filtering? or some sort of firewall like pfSense?

1 Like