javascripthtmlcanvassecurity-by-obscurity

Drawing parts of a Blob to html canvas without data urls in Javascript


I'm testing something out using a webapp where users can see a few pieces of an image but not all of it at once. The whole data is sent down to the client and decrypted client-side. That data is then in base64 so I simply use:

img.src = 'data:image/jpeg;base64,' + imgdata;

In order to display it. Then I can call

my2Dcontext.drawImage(img, x, y, width, height)

and all would be good, right?

Except no, the original full data is incredibly easy to download. Just copy the data source from the image and then download or open inspector and download it that way.

For this reason I'm wondering how I could conceivably get the data from imgData onto the screen without having to put it all on the screen.

Is there any way to render part of an image from data onto canvas without create things like full-image data urls?

I know this is an odd case, but if any of you guys have any creative ideas I'd really appreciate it!

(P.S, I'm aware this is essentially security through obscurity in some sense and that if they can display the parts separately on the screen they can just patch them together. I'm just trying to stop the easiest level of extraction. Thanks)


Solution

  • Well, you cannot actually protect displayed images from a user determined to get the image. A simple screen grabber tool then can be used to patch together the tiles/parts of the image. An advanced user can inject a script to do the same automatically.

    However, for the sake of creative approaches:

    Image Data Obfuscation

    There is the option of obfuscating the data itself before delivery so that if any attempt is made to download the source it will be useless. When shown on canvas you can "decode" the data so it shows properly (but then referrer again back to screen grabber tool, the option user has to save the canvas as image and so forth).

    Obfuscating doesn't have to be very complex though, you need to find an algorithm that can mess with the bitmap data for the source, and likewise a way to put it back in order - this will of course come with its own challenges for lossy formats such as JPEG; PNG is almost required here (and did I mention that a more advanced (?) user could also extract the code that decodes the content).

    Video Encryption (EncryptedMediaExtensions API)

    Another way is to provide the images as a video stream (each part could be a frame) protected with DRM. This may have some influence in the case of screen grabber depending on OS/hardware support etc, but don't bet on it (even if the browser support DRM)...

    Without DRM it's simply a matter of obtaining the video and use tools such as ffmpeg to extract each frame.

    Watermarking

    A widely adopted solution, at least in the field of stock photos, is to watermark each preview and tile. This will level up the game and force the determined user to fire up Photoshop or something similar, and to spend more time than what is considered fun in order to remove them; with variable result.

    This may or may not be suitable in your case.

    Value?

    Personally, I would not spend the time trying to do this. The efforts put into this will soon enough be worked around.

    Depending on the purpose, watermarking tiles/parts (at source) is probably the more efficient solution.