2

I'm trying a figure out how I can hide an image's url when looking at the console or source code.

I've seen others asking about this to prevent users from downloading the images, but this is not the problem - in fact they should be able to download/save the images.

The real reason is because my users are uploading images on my website, to a third-party storage service like cloudinary. I don't want the users to know where the images are going, because I'm afraid they could manipulate the data sent or received. This is just an additional security measure, even after checking that the images sent/received are indeed image urls and not malicious code or anything.

What do you recommend for hiding the urls in the console? I'm completely out of ideas on where to start.

To elaborate a bit: The user clicks 'browse for files' on my website, then clicks 'upload'. The files get transferred to cloudinary for storage. My website then fetches the image url(s) from cloudinary, stores the url in my database, and displays them in div boxes on the user's profile. Something like this:

<div class="listing_img" style="background-image:url('.$img_url.');"></div>

Where $img_url is a row from the database.

Sort of like an image-storage website, but not exactly, people won't come to my website for storing images. Users won't at any stage get to see which API url their images are being sent to, unless of course they see the 'img src=akdklasdjakl' inside the browser console.

I'm not sure if this is the correct approach, but it doesn't seem like a bad idea.

anna
  • 127
  • 2
  • 10
  • If the image URL's _"displays them in div boxes on the user's profile"_ what do you mean by _"hide the image urls"_? – guest271314 Feb 02 '19 at 16:02
  • 1
    This is what I mean: ```
    ```. The div content is empty, but the console will still display the url.
    – anna Feb 02 '19 at 16:03
  • Not following what you are trying to achieve and why. – guest271314 Feb 02 '19 at 16:04
  • Hmm...how do I explain? I'm displaying a bunch of images on my website, which some random user uploaded, but if they check the browser console or right-click and view the source, the url of the image should not display. Instead of seeing ```
    `` they should simply see ```
    ''' or something similar.
    – anna Feb 02 '19 at 16:06
  • Are you trying to not disclose the fact that you are using an external service to store user data? – guest271314 Feb 02 '19 at 16:06
  • 1
    Yes, exactly. The users can know that their images are being stored elsewhere, but they should not know exactly where. – anna Feb 02 '19 at 16:07
  • Does client-side code make the request to the external service? Why do you not want to disclose where the users' data is being stored? Are you trying to appear as though your own site is storing user data, to bolster or sustain your own sites' potentially perceived functionality to users? How is the question about security? – guest271314 Feb 02 '19 at 16:08
  • 1
    Yes, I think so, because it's being done through JavaScript or Ajax. The reason I don't want to disclose it is because, let's say for example, the user knows that their images are going to ```domain.com/folder/username```, so it would be pretty easy to upload images to another user's folder just by changing that value. This could be a bit problematic, firstly because I use the folder structure to divide user images, and also because I prefer that the user does not know which third party service is being used, that just gives them more info on 'which' website can be hacked/manipulated. – anna Feb 02 '19 at 16:13
  • 1
    If the image is stored on the cloud server and you want the user to download it from there, you need to tell the client where to download it from (as that is what you want it to do). – Solarflare Feb 02 '19 at 16:14
  • 1
    And no, it's not to 'bolster or sustain' anything, my website isn't about image uploading in the first place. I'm using a third-party tool cause I don't want to bother about getting a bunch of computers just to store images which users may or may not use (like, profile pictures). – anna Feb 02 '19 at 16:14
  • 1
    @Solarflare it's not an image downloading website...it's a normal website where users can have profile images and so. If another user wants to download or save that image, he should just right-click on it, and then it gets saved to his pc as normal. But at the same time, he doesn't know 'where' it was downloaded from (obviously i'll use a secure site with ssl, like cloudinary) – anna Feb 02 '19 at 16:16
  • How could a user upload images to another users "folder"? Not disclosing how user data is handled and stored is far more problematic (for various reasons) than one or more users attempting to upload images _to_ another users' "folder". Since the request to the external service is made client-side, no, you cannot "hide" that fact from users. – guest271314 Feb 02 '19 at 16:16
  • 1
    The image could be requested from your server acting like a proxy. – Pinke Helga Feb 02 '19 at 16:19
  • 1
    Why are you asking me so many questions? I'm sure there are hundreds of reasons to want to hide an image url. I don't know how users could manipulate it, I just know that you must always, no matter what, treat user-data as insecure and not trusted. – anna Feb 02 '19 at 16:19
  • 1
    You need to keep a database to map a local url/path with a remote image path and passthrough the remote image to the browser. Options are CURL or file_get_contents() (when remote url's are allowed) for example. – Raymond Nijland Feb 02 '19 at 16:20
  • @anna _"Why are you asking me so many questions?"_ The premise of the question, from perspective here, is unethical. And potentially can cause more problems than what you are trying to solve. Also, it is not possible where the code served with the `document` makes request to the third party service. All network requests and responses can be downloaded in a single `.har` file. There are other examples in the wild of services not disclosing what they are doing with user data, worse than this example, and hardly ever reassuring to users once discovered. – guest271314 Feb 02 '19 at 16:23
  • 1
    @RaymondNijland That's a good idea, it sounds like 'masking' an image url. From my understanding, you're saying that the mysql table should include 2 image url fields, one original and one 'masked'? And the php code is there to 'parse' it so that the user never actually sees the original url in the browser? – anna Feb 02 '19 at 16:27
  • @anna One example of a service not notifying the user or subsequently disclosing that user biometric data is being recorded and sent to a remote web service (potentially used for other undisclosed purposes; stored forever) [Chromium/Chrome `SpeechRecognition` implementation records end-users' voice and sends the users' voice to an external web service #4196](https://github.com/Fyrd/caniuse/issues/4196). Once that path is taken the question becomes what else is not being disclosed. Simpler to provide disclosure as to what you are doing with user data instead of trying to "hide" your practices. – guest271314 Feb 02 '19 at 16:30
  • Yes that is what i meant with the comment @anna – Raymond Nijland Feb 02 '19 at 16:30
  • You just need the original url. Each image requested via your server has an id. Your server requests the image from 3rd party and serves it as it would be stored on your own server. – Pinke Helga Feb 02 '19 at 16:31

2 Answers2

2

You can try using a data-uri to add the image data rather than the image url - as you would for inline images. So, in CSS you could try:

style="background:url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKu..... etc) no-repeat;"

As example:

This uses a remote image but you can use local filepaths - even those outwith document root.

    $source='http://jumanjipets.co.uk/wp-content/uploads/2018/02/koi.jpg';
    $contents=file_get_contents( $source );

    printf( "<img src='data:image/jpeg;base64, %s' />", base64_encode( $contents ) );
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • 1
    base64 can be easy be decoded? this code is "security by obscurity" – Raymond Nijland Feb 02 '19 at 16:18
  • I did mention 'the common user' @RaymondNijland :) If a clued up user really wanted to see the url, they'd make a way to find it. My concern is simply to prevent an 'easy' way to use other user's folders. This answer is headed in the right direction, of course it would be excellent if it wasn't decodable. – anna Feb 02 '19 at 16:23
  • the image data can be decoded but the actual path remains unknown. Anytime an image is rendered in the browser it is available - but at least with using the image data uri the path is not known – Professor Abronsius Feb 02 '19 at 16:25
  • "the image data can be decoded but the actual path remains unknown." the remote url including the path will be seen after base64 decode!! – Raymond Nijland Feb 02 '19 at 16:32
  • 2
    you might want to look at that again....it is not the path that is `base64 encoded` but that actual image data - the path is no longer required to display the image – Professor Abronsius Feb 02 '19 at 16:34
  • This seems like the solution in my case... @RamRaider – anna Feb 03 '19 at 15:12
  • it could be a solution @Anna ~ you would need to use php to obtain the image data as a string but the path to the image would no longer be an issue – Professor Abronsius Feb 03 '19 at 15:14
  • I haven't tested it, but the theory is exactly what I'm looking for. Brilliant :-) – anna Feb 03 '19 at 15:16
  • Another benefit would be that the image would not necessarily need to be under the document root as typcially would be the case for the images directory - so long as php can read the file the returned data-uri is all that is required. – Professor Abronsius Feb 03 '19 at 15:19
  • @RamRaider I heard that base64 increases the image size by around 37%, or 4/3. That might be one tiny disadvantage, since we all like smaller/speedier uploads. What do you think? – anna Feb 03 '19 at 15:34
  • 1
    you'll need to weigh the pros and cons for yourself I'm afraid. Chances are that gzip compression is enabled on the server ( or can be ) so you could save a little like that... Perhaps some benchmark tests might need to be done to determine if one method is noticeably slower – Professor Abronsius Feb 03 '19 at 15:41
0

Another way is to serve the images by your own server. Just stick to a convention of eg. image IDs to convert them back to the original image URL.

The user gets a page with <img src="/img-1.jpg">.

Redirect the url starting with "^/img" to a script to retrieve the image on your server and return the image from there.

RewriteRule ^/img-(\d+) convert-img-id-to-url.php?id=$1 [L]

The user can't see the original source. Only you can link the image ID to the source.

Phil
  • 422
  • 1
  • 5
  • 20