Jump to content

Unauthenticated access to images by itemid


Recommended Posts

Posted
1 minute ago, Happy2Play said:

 you can get really anything you want and if my images are some important that I got from somewhere else are so important you can have them.

But to each their own.

That's nice that you don't care, but there are many people here who would prefer and rightfully expect for their software to be at least somewhat secure.

darkassassin07
Posted

Good to know Emby as a personal media server can't be trusted to keep personal media, well, personal.

 

This wouldn't be much of a concern if all we were talking about was movie/tv posters/backgrounds/etc; but this vulnerability includes ALL images on the server. Camera upload enabled? Family photos/videos stored on emby? Got a porn library or two? It can all be vewed by anyone with the domain/ip to your server. Just gotta feed it some random numbers, and you will get no alerts to such activities.

 

 

 

I stopped trusting Emby with such media long ago, too many bugs with permissions; but this will ensure I never give it access to that media again.

  • Agree 5
Posted
1 hour ago, darkassassin07 said:

This wouldn't be much of a concern if all we were talking about was movie/tv posters/backgrounds/etc; but this vulnerability includes ALL images on the server. Camera upload enabled? Family photos/videos stored on emby? Got a porn library or two? It can all be vewed by anyone with the domain/ip to your server. Just gotta feed it some random numbers, and you will get no alerts to such activities.

This is exactly why this is so bad. A lot of people are using emby to view or share more than just movies and tv shows.

I had a dedicated emby instance for family pictures and videos. I even bought a 2nd premier license for it. My intention was to be able to easily share with extended family. As soon as I discovered this flaw I disabled that instance and am still looking for a viable alternative.

I doubt that most people using emby for these use cases would be comfortable knowing that anyone could arbitrarily pull images off of their server with such ease.

This isn't just a problem for internet facing servers either. It could just as easily be exploited by anyone with local network access. Whether that be a kid, a curious/malicious guest, etc. 

  • Agree 1
tmurphy2792
Posted

Welp, this is great to find out as I've just recently started using the "Camera Uploads" feature for automatic photo backup for my wife and I's phones. While our stuff is quite boring family pictures and such, I'm not fond of the idea of our photo library being exposed to be easily downloaded by a simple crawler.

 

Does Emby have a plan here for a solution? Considering that solution is 4 years in the making, is there a current short term solution?
I'm guessing we basically have 2 options here: Don't use Camera Uploads, or don't expose your emby server to the web?

Posted
54 minutes ago, tmurphy2792 said:

 

Does Emby have a plan here for a solution? Considering that solution is 4 years in the making, is there a current short term solution?

I'm hoping the increased attention on this will bump it up much higher on the priority list to be fixed properly.

There may be a way to mitigate it for the time being with a reverse proxy. So far I've had no luck with this and there are no guidance or working configurations/examples. 

tmurphy2792
Posted
16 minutes ago, Clackdor said:

I'm hoping the increased attention on this will bump it up much higher on the priority list to be fixed properly.

There may be a way to mitigate it for the time being with a reverse proxy. So far I've had no luck with this and there are no guidance or working configurations/examples. 

Good to know, I may need to look into something like this.

I'm truthfully a newbie with this networking stuff so I was thinking disable the wan altogether for my emby server (both in router and emby server settings) then just use my wireguard vpn to access emby remotely. Works acceptably enough in my case as my wife and I are the only two using my server, and vast majority of the time we're on LAN anyway.

Posted

This isn't an Emby thing. It's this way all over the Internet. You want images to load fast and be able to get pulled from the browsers cache once they've been downloaded the first time. Static content, be it graphics, html, java script, video segment, etc are meant to be able to re-used for a period of time without having to retrieve them on every use. The internet depends on this working in this fashion.  Organizations of all sizes from companies to ISPs make use of proxies or transparent proxies (you won't even know it's there) to hold static information when possible, to save bandwidth and deliver content quicker as the resource will already be local. Mobile operators do this and more. Not only will they cash things like images, but they also likely re-optimize them as well delivering a picture that's been scaled down to look the same on hand-held devices but save bandwidth.

Content Delivery Networks (CDN) require this in order to be able to move the content closer to a user with regional edge servers. Many ISP do this as well in a transparent fashion as well so a 1000 users hitting Facebook will have content in common that won't need to be requested. 100 users watching the latest movies just posted on Netflex or Prime can be served up from local ISP cache vs using bandwidth for every user.

There are methods that can be used to obfuscate static content by making it look dynamic, but then it can't be cached.  Emby could also require an authorized session to delivery anything including images but they share the issue of "busing" the ability to cache the images. Nginx or other local reverse proxy caching is lost, every use of an item requires a delivery from the server.  That's a lot more work on the server having to deliver much more data over and over as well as a lot more overhead needed for session/authorization management.

In another thread, Luke mentioned the image retrieval code could be changed to require an API.

That would stop private images from being exposed but would negatively affect image caching in general.
I think a better approach would be to keep the current URL as is
http://{public domain}/emby/items/{increment number}/images/primary
But never deliver the content with that URL if the content is from "private" content areas such as Camera Upload or Home Video and Photos libraries it would require a different URL that includes a key some kind. The content would be delivered assuming the user has access to that content.

For security I'd code it so the current URL only delivers content associated with sections in (list) while everything else would require an authorized key.  This way, it's future proofed from a new addition or feature slipping through the cracks. Any new type of content types would have to be explicitly added to the list above in code to deliver content without a key.

This approach would allow caching as usual from local nginx (or other reverse proxy) to transparent proxies or CDN deliveries, while protecting private content areas requiring authentication. This would provide the security required while providing the best performance possible.

Each client app should be upgraded to directly support this, but the server could provide an interim solution to bridge the gap until each app is upgraded. For example, if the client is a Roku and not version X or higher (with new handling) accessing private content using the existing URL it would determine If the user has access to that content as well as check to see if the device has already been authenticated for the session.

I just want to make sure any implementation added, doesn't adversely affect performance or the ability to cache images for the main library as you WANT/NEED them to be non-secured and fully cacheable.

  • Like 3
Posted

@CarloThis does sound like an agreeable solution. I think we can agree that being able to access personal photos and video thumbnails is what's actually problematic. People using emby for private photos and videos should be able to have full confidence that they will stay private. TV shows and movies aren't nearly as important. It's definitely not worth losing the benefits of caching to go full paranoid mode.

Posted (edited)
18 hours ago, Carlo said:

This isn't an Emby thing. It's this way all over the Internet. You want images to load fast and be able to get pulled from the browsers cache once they've been downloaded the first time. Static content, be it graphics, html, java script, video segment, etc are meant to be able to re-used for a period of time without having to retrieve them on every use. The internet depends on this working in this fashion.  Organizations of all sizes from companies to ISPs make use of proxies or transparent proxies (you won't even know it's there) to hold static information when possible, to save bandwidth and deliver content quicker as the resource will already be local. Mobile operators do this and more. Not only will they cash things like images, but they also likely re-optimize them as well delivering a picture that's been scaled down to look the same on hand-held devices but save bandwidth.

Content Delivery Networks (CDN) require this in order to be able to move the content closer to a user with regional edge servers. Many ISP do this as well in a transparent fashion as well so a 1000 users hitting Facebook will have content in common that won't need to be requested. 100 users watching the latest movies just posted on Netflex or Prime can be served up from local ISP cache vs using bandwidth for every user.

There are methods that can be used to obfuscate static content by making it look dynamic, but then it can't be cached.  Emby could also require an authorized session to delivery anything including images but they share the issue of "busing" the ability to cache the images. Nginx or other local reverse proxy caching is lost, every use of an item requires a delivery from the server.  That's a lot more work on the server having to deliver much more data over and over as well as a lot more overhead needed for session/authorization management.

In another thread, Luke mentioned the image retrieval code could be changed to require an API.

That would stop private images from being exposed but would negatively affect image caching in general.
I think a better approach would be to keep the current URL as is
http://{public domain}/emby/items/{increment number}/images/primary
But never deliver the content with that URL if the content is from "private" content areas such as Camera Upload or Home Video and Photos libraries it would require a different URL that includes a key some kind. The content would be delivered assuming the user has access to that content.

For security I'd code it so the current URL only delivers content associated with sections in (list) while everything else would require an authorized key.  This way, it's future proofed from a new addition or feature slipping through the cracks. Any new type of content types would have to be explicitly added to the list above in code to deliver content without a key.

This approach would allow caching as usual from local nginx (or other reverse proxy) to transparent proxies or CDN deliveries, while protecting private content areas requiring authentication. This would provide the security required while providing the best performance possible.

Each client app should be upgraded to directly support this, but the server could provide an interim solution to bridge the gap until each app is upgraded. For example, if the client is a Roku and not version X or higher (with new handling) accessing private content using the existing URL it would determine If the user has access to that content as well as check to see if the device has already been authenticated for the session.

I just want to make sure any implementation added, doesn't adversely affect performance or the ability to cache images for the main library as you WANT/NEED them to be non-secured and fully cacheable.

It IS an Emby thing because as you have repeated above - it's because emby is just incrementing the id.  If it used a hard to guess random id - ideally alpha numeric, then we wouldn't be having this conversation because the 'key' as you put it, would be 'impossible' to guess in the first place.

A quick solution is to simply increase the numerical langth of the id and randomise it - that way, any image is much harder to guess but you can retain the clients/api etc.   It's not ideal, but it's better than what we have today.

Not 100% sure where caching comes into this - the idea is to stop a brute force access to the image in the first place.   Once it's been read, yes, of course it's in a cache 'somewhere' but so what if it is ?  It will have a TTL and be removed from the cache in due course.

Edited by rbjtech
  • Agree 1
darkassassin07
Posted

 

18 hours ago, Carlo said:

I think a better approach would be to keep the current URL as is

http://{public domain}/emby/items/{increment number}/images/primary
But never deliver the content with that URL if the content is from "private" content areas such as Camera Upload or Home Video and Photos libraries it would require a different URL that includes a key some kind. The content would be delivered assuming the user has access to that content.

For security I'd code it so the current URL only delivers content associated with sections in (list) while everything else would require an authorized key.  This way, it's future proofed from a new addition or feature slipping through the cracks. Any new type of content types would have to be explicitly added to the list above in code to deliver content without a key.

This approach would allow caching as usual from local nginx (or other reverse proxy) to transparent proxies or CDN deliveries, while protecting private content areas requiring authentication. This would provide the security required while providing the best performance possible.

[....]

I just want to make sure any implementation added, doesn't adversely affect performance or the ability to cache images for the main library as you WANT/NEED them to be non-secured and fully cacheable.

 

The only real note I have on this approach is you'd have to add a toggle to each library to explicitly mark it as private or not, as some people use regular 'movie' or 'tv shows' type libraries for personal content. Then you'll have people that don't really understand what that toggle means.

Posted
1 minute ago, darkassassin07 said:

 

 

The only real note I have on this approach is you'd have to add a toggle to each library to explicitly mark it as private or not, as some people use regular 'movie' or 'tv shows' type libraries for personal content. Then you'll have people that don't really understand what that toggle means.

Hmm -  I should not have to tell emby it's private - it should be out the box !

Emby need to fix the inappropriate method to assign id's when used on the internet - for local, fine, it makes little difference, but when exposed to the internet - the mindset of security needs to be changed - radically - you are well aware of this ... ;)

  • Agree 1
Posted
1 hour ago, rbjtech said:

A quick solution is to simply increase the numerical langth of the id and randomise it

We used to use GUIDs - which is why the initial design of this was of no real concern.  In 4.6 or 4.7 I don't remember which, though, we switched to the actual database IDs which brought about significant performance improvements throughout.

  • Like 1
  • Thanks 1
Posted

 

2 hours ago, darkassassin07 said:

The only real note I have on this approach is you'd have to add a toggle to each library to explicitly mark it as private or not, as some people use regular 'movie' or 'tv shows' type libraries for personal content. Then you'll have people that don't really understand what that toggle means.

I do agree on this point. Giving admins a toggle option would be the ideal approach from a privacy vs performance standpoint and cover most use cases/library arrangements.

Perhaps something along the lines of "Enable/Disable Public image Caching" in each library's settings. Have a description that states something like "If enabled it's possible for library images and thumbnails to be viewed publicly by itemID without authentication. Improves image loading performance in some situations such as behind a reverse proxy."

Posted
15 hours ago, Clackdor said:

 

I do agree on this point. Giving admins a toggle option would be the ideal approach from a privacy vs performance standpoint and cover most use cases/library arrangements.

Perhaps something along the lines of "Enable/Disable Public image Caching" in each library's settings. Have a description that states something like "If enabled it's possible for library images and thumbnails to be viewed publicly by itemID without authentication. Improves image loading performance in some situations such as behind a reverse proxy."

Disagree.  The user should never have to 'decide' if they want their private image files exposed to the internet or not due to lack of a secure design.   If there needs to be a 'balance' of security vs performance, then that is fine.

Perhaps I'm missing the point on why this 'id or key' cannot simply be different/random for each item - I'm not suggesting it's changed for every access (as that would obviously screw up any cache) but by simply by making it different for every item, rather than an incremented number, the processing/http request required to find the next one by chance/brute force is significantly increased.

  • Agree 1
Posted
3 hours ago, rbjtech said:

Perhaps I'm missing the point on why this 'id or key' cannot simply be different/random for each item - I'm not suggesting it's changed for every access (as that would obviously screw up any cache) but by simply by making it different for every item, rather than an incremented number,

Because the IDs are coming from the database.  They are different for each item but they are just numbers.  At this point, I don't see us trying to completely change our IDs again.  instead, this will need to be addressed with an API key like other authentication.

The issue is, there are apps out there that are either very difficult or even impossible for us to update and this would break them.  But, that may just be the way it is.

  • Like 1
  • Thanks 1
Posted

@CarloGood write-up, but most of it is hardly applicable here. You're treating the emby server software as if it's a public facing website when it's more of a private media gallery. Caching, bandwidth, and etc is hardly a concern here for the vast majority of users, and I think it's safe to say that the most would be ok with a few extra milliseconds of load time if their content was actually secure.

  • Agree 4
Posted

No, you would be surprised by the number of people running reverse proxies. A lot of people use CDNs as well but most use Cloudflare.  Some people are behind a CG-NAT with a way for people to get to their media server so instead of using a relay or VPC or VPN they get a domain name, change the authorized DNS servers to point to Cloudflares. Then using a Cloudflare Zero Trust tunnel they get the benefit of people hitting the Cloudflare CDN directly which solves the CG-NAT problem.  The also don't need to open any point so nothings gets into the network except Cloudflare through the tunnel. No one on the internet knows your IP address as they only see the CDN IP address.  They get all the caching, special CDN features, optimized delivery (images are fast), etc as well as get protection against DOS attacks, bot attacks or scans since the CDN blocks that none-sense.

Most due that on a free Cloudflare account as well!  We make a change in the Cloudflare dashboard using a rule to specify not to cache anything starting with a couple of specific URLs. Theses are the URLs used by Emby for music and video media. This is to stop them from caching the media content and copying it to different regions or to edge servers. We try not to abuse their service. A portion of people using Cloudflare also use a reverse proxy as well to direct traffic to other services they have.

The caching does make a big difference, I just want to make sure that a patch/solution for the issue doesn't break caching as it doesn't need to.

  • Sad 1
pünktchen
Posted

@CarloBut does Cloudflare ever make a request on its own to the Emby server? I don't think so. It will forward the image request with an auth header, done by an Emby client, to the Emby server. The Emby server will respond with the image file to Cloudflare. Cloudflare will cache the file and serve it to the Emby client.

Am i wrong here? What i'm missing?

pwhodges
Posted
19 hours ago, ebr said:

Because the IDs are coming from the database.  They are different for each item but they are just numbers.

But putting larger, better randomised numbers into the database would minimise the possibility of speculative access to images which have not been properly requested, without affecting anything else.

Paul

Posted
4 hours ago, pwhodges said:

But putting larger, better randomised numbers into the database

My point is we do not put the numbers into the database.  The database generates them.

Whether or not that part could be easily changed, I'm not sure but then you have to have a routine checking for uniqueness on each insertion.  With GUIDs we could pretty much guarantee uniqueness - with plain integers, we could not.  Also, true numbers (which is one of the things giving us performance boost) can only be so large....

Posted (edited)
On 11/4/2024 at 7:13 PM, pünktchen said:

@CarloBut does Cloudflare ever make a request on its own to the Emby server? I don't think so. It will forward the image request with an auth header, done by an Emby client, to the Emby server. The Emby server will respond with the image file to Cloudflare. Cloudflare will cache the file and serve it to the Emby client.

Am i wrong here? What i'm missing?

Not on the free plan.  Some of the business plans provide for an update method. You deposit a text file at a specific location on your website that is encrypted. By schedule Cloudflare will check the file for new URLs to grab/replicate. They also allow you to send the file to a specific location which they process as soon as they receive it which I think is smarter.


What I was thinking was rewriting the URL containing images.  Right now, it looks like:
/emby/items/ID/images/primary
That's very easy to increment and guess valid URLs.

Instead, the server writes the URL like this:
/emby/items/80e2dfecb5f54513ad4e2e6217d36fd4/17945
The server created an md-5 hash using a secret code on the ID   (/emby/items/md5-hash/ID)

If anyone changes anything after /emby/items/ they would be changing the hash or ID. Either way it becomes a broke link.  This is because the server would compute an md-5 hash on the ID then compare it to the hash in the URL. If they NO MATH, NO IMAGE

You can no longer "increment" the ID as the md-5 hash wouldn't match.  All images would still be fully cached, but no one could guess a URL unless they had been logged in and had proper access to the area the images belonged to. Using Cloudflare or a reverse proxy you could ban a user IP quickly.

Pretty simple actually, so I'd ask for two additional features.
1. Just like in Networking have a switch to have the server do this work, or off-load it to a reverse proxy.
2.  Have the server write the URL like this /emby/items/Parent ID/ID/images/primary if process is off-loaded to reverse proxy.

It has a new parent ID, Without, knowing anything about that Parent ID I could go into my movie library scroll through a few pages and look at the logs to see what Parent ID my movies are. Next my TV Shows, the Music. If I know those 3 Parent IDs I could skip the md-5 hash generation both incoming and outgoing. Since there just meta images from the Internet to start with.

Edited by Carlo
Posted

Or... just add the API key to the url...

The problem, again, is the impact to the current consumers of the url.

  • Confused 1
Posted
55 minutes ago, ebr said:

Or... just add the API key to the url...

The problem, again, is the impact to the current consumers of the url.

Probably not advisable, unless it's an API purely for the images - you wouldn't want to post an API with admin as part of the URL for obvious reasons ...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...