1

I'm uploading a canvas image to my server by AJAX using a method like this:

myCanvas.toBlob( function( blob ) {
    var fdata = new FormData( );
    fdata.append( 'myFile', blob );
    $.ajax( {
        url: 'http://myScript.foo',
        type: 'POST',
        data: fdata,
        processData: false,
        contentType: false
    } );
}, 'image/jpeg', 0.9 );

(with thanks to https://stackoverflow.com/a/8244082/1180785)

But according to Mozilla,

toBlob […] Returns a Blob object representing the image contained in the canvas; this file may be cached on the disk or stored in memory at the discretion of the user agent

(https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement)

It's quite important for my program that the image is not kept (not as a restriction, but as a privacy concern). So I need to know if there is a guarantee that this possible cached copy will be deleted, and when. There's also a potential risk of undelete programs finding it, so I'd like to know if I can overwrite the data or force a secure deletion in some other way.

If it's possible to achieve the same result without risking a locally-cached copy, it would be even better. Encryption is also an option if that's possible.

I only care about modern browsers, supporting getUserMedia specifically, so no IE (I have a Flash fallback for older browsers which processes everything in memory).

Community
  • 1
  • 1
Dave
  • 44,275
  • 12
  • 65
  • 105

2 Answers2

0

In all likeliness the blob is deleted when either,

  1. there are no references to it (garbage collection)
  2. the tab/window is closed

In that context "cache" doesn't mean over a long period of time, but rather not recalculated every time its accessed.

Caching the content long term would be a waste of storage space, as a canvas is designed to by dynamic. If it was static content, an <img> should be used.

I haven't looked at any source code, but this is a logical conclusion. After jQuery stops referencing the blob (when the request is sent), it should be picked up by the garbage collector and discarded.


Secure deletion is very low level and browsers would never allow it. It basically works by writing to specific addresses on the hard drive, which could be miscalculated and ruin thousands of files (in a heavily fragmented partition). If they store it to the disk, it will be recoverable by computer forensics.

Brigand
  • 84,529
  • 20
  • 165
  • 173
  • I agree with your guesses, but unfortunately "in all likeliness" isn't strong enough when dealing with people's privacy. – Dave Aug 21 '13 at 22:10
  • I understand. I can't seem to find anything on Google, so it might require taking a look at the Chrome and Firefox source. If you can't understand it (I wouldn't be able to) try asking a developer with commits containing "blob". – Brigand Aug 21 '13 at 22:26
  • Well, I can just about navigate FireFox's source when I need to. I've never tried Chrome before. This could be fun! (Also I believe Opera is still closed source?) – Dave Aug 21 '13 at 22:39
  • Update: FireFox's file handling code is a labyrinth! I am completely lost in method after method, class after class. And I swear there must be some preprocessor magic going on which I've never seen before, because I've found macros used that I can't find a definition for anywhere! – Dave Aug 22 '13 at 19:01
0

If privacy and security is important you should consider generate a data-uri from the canvas instead of a Blob object.

As the blob may or may not be stored (cached) temporary on disk the file will be subject to security situations (ie. undelete as you mention). A memory file/string will of course be available for a memory scan but this is as close as you'll get to "secure" when getting an image from canvas for transfer.

A data-uri is usually* generated in memory only and contains typically a base64 encoded image (if your image is severely large there is still the risk of it being paged to disk).

*) implementation dependent, e.g. it's more likely that mobile browsers will use a temp-to-file if there is scarce with memory resources available - however, this possible behavior is not documented.

To get a data-uri use instead:

canvas.toDataURL();

You can optionally specify an image type (default is PNG):

canvas.toDataURL('image/jpeg'); //optional second parameter is quality [0.0, 1.0]

Another option is to extract the pixels directly from canvas and store in a (typed) array. The data can then be transferred as-is or one can use a compression library to compress to for example zip before sending the data.

However, this approach is the least efficient.

  • This is a possibility (needs some special setup on the server but that's no issue), but is there a better guarantee that `toDataURL` won't save to disk (compared to `toBlob`)? I was under the impression that it internally created a file (not sure if virtual or real), then set the string to a representation of that file. Also I'm aware of the potential paging and memory scanning, but that's unavoidable no matter how I set things up. – Dave Aug 22 '13 at 18:56
  • 1
    @Dave usually the file will be generated in memory unless it's very huge and there is not enough physical memory (available to browser) to generate it. I say usually as this will also be implementation dependent - e.g. for mobile browsers temp-to-disk may be more likely. A third option is to retrieve the pixels from the canvas and store as *typed array* and send that to server (there exist compression libraries for JS but efficiency may become a problem with this approach). –  Aug 22 '13 at 19:36
  • OK, I think using a custom compression library would be overkill (especially since there's still a chance of it being stored on disk). It's a shame there's nothing which can guarantee security, but I think that for now I'll go with `toDataURL`. At least that way, even if it does get stored to disk, it would take somebody with some knowhow to read the image (being base-64 encoded). Thanks. – Dave Aug 23 '13 at 12:57