domingo, 11 de diciembre de 2011

Security issue on Facebook images and the browser caches. And how can do the social networks to increment the security on the images that the users share

Some weeks ago I read an article on a spanish newspaper:
The idea is stupid, if you have the image, you can share it, downloading it, doing a screenshot, etc, and you don't have any way to get the complete URL of the image if the user don't share the image with you.
Ok, but I thought, what happens with the cache of the browser?, all the browsers catch all your images to increase the speed, and if someone have access to your computer after you, he can see your private images only looking into the cache directory of the browser. This is a real problem, for example, you can have commited pictures, and your parents / wife / etc can see these looking for images into the computer HD.
I did a video that shows it:

As you can see, I visit a picture of one of my friends, and after this I close my session on Facebook, but the picture is still on my HD, it was stored on my cache directory. Is the same problem if you remove the picture, or revoke the access to the picture to some users.
What can Facebook (and the rest of pages who works with pictures) do to avoid this?:
  1. They can set the cache control as no-store, no-cache, etc for all the pictures who came from the static servers. But they will increase a lot the bandwidth usage and the user experience will be awful.
  2. They can encrypt all the pictures and serve it using the cache with the max TTL allowed, and send using another query to the backend that can check if the user are authorized, etc, a token to decrypt this image, the decryption can be done using JavaScript, this is easy and faster than download the picture all the time.

I did a proof of concept of the second option, and I'll explain it.

The Proof of concept:

    Ok, the steps to do this are the next:
  1. Take the picture from the user.
  2. Convert the picture to base64 (this step can be avoid with a more complex algorithm on the JavaScript code, but to the proof of concept is valid)
  3. Get the SHA1 of the picture, this will be used as key to encrypt/decrypt the image, but could be used to be sure that don't exist any error into the transmission. To this proof of concept I'm using it only to decrypt/encrypt.
  4. Save the picture encrypted into the HD (on a final version it will be stored into the static servers)
  5. Save the SHA1 into the database with a flag to give or revoke the access to the users to this picture.
  6. When a user wants to see the picture it will be served directly from the static servers, and the token will be send from the backend server after the security checks on another query that will not use the browser cache.
  7. The browser will save on the cache directory the encrypted image, then nobody can have access to it if the backend server don't send the key.
  8. If the user reloads the image, the browser wouldn't ask for the picture again, it will take the picture directly from the user cache, and will ask only for the key that will be send as JSON if the user have access.

    Using this method we can:
  1. Revoke the access to an image when we want, the user can't get the image from the cache of the browser, then nobody will see this image again.
  2. Share the images to another users without authorization will be more complex (yes, you can, but not only sharing the link.
  3. If someone have access to the list of images contained into the static server, he can't do anything with the images.
  4. Will be more complex use the static servers to serve images to another site (stealing bandwidth).

You can see the proof of concept here:
Use the network tab of the Firebug to see the queries that the browser are doing to the server.
You can click on the "Revoke access" link, and only the administrators will have access to your images (the key is not served to the common users, but the image is still into the server HD, and the key into the database)
You can see a video about how this works here:

You can download the code from here:

I used this libraries to encrypt / decrypt on AES:

No hay comentarios:

Publicar un comentario