Determine filetype by magic number - javascript

I had to check filetype in file uploader to determine if file was image (jpg, png) and I decided to do it by reading file's magic number (4 first bytes) with FileReader but I have some doubts about this method:
Is this method safe? Is there a way to upload non jpg file as jpg with this method?
I've seen filetypes with different magic numbers size like 2, 4, 6 bytes... So If I had to make a generic method to determine not just image filetype but the others as well, I would have to read the maximum amount of bytes (to determine largest magic number) from the file, right?

It's not safe. Problem is not only in magic numbers but already in that you try to validate it on client side.
Form can be uploaded directly from a script bypassing your client side validation.
Correct way to do it is to validate everything on server side using proven techniques.
Right. Different file formats have different magic numbers on different offsets. But still if you care about security - dont trust anything.

Related

Client side validation of png file in javascript

I have a simple web application to manipulate image files in the browser.
It is entirely client side. I had some questions about the safety of the operation here : Is this client side application secure?
I want to validate the files to make sure only allowed formats can be 'uploaded'. I put uploaded in quotations because, I'd like to repeat, everything happens on the client side in javascript.
PNG files specifically
I am learning about the structure of png files and I am thinking of using the fileReader object and the method readAsArrayBuffer() to read the bytes of the png file so that I can evaluate the first 8 bytes of the header (137 80 78 71 13 10 26 10) along with the chunk types (like IHDR, IDAT, IEND etc.) and the CRCs. In fact I have already done so but it isn't a part of my web app. Basically, when a user tries to 'upload' a file, my app would spot check some key bytes of the file and determine roughly 'OK, this is a png file. It's ok to work with this file'.
Would this be a good enough validation?
My reasoning for this precaution, even to this whole thing is client-side, is to protect an unsuspecting end user who might 'upload' a file that looks like a png, but which actually contains some harmful script with it.
If this isn't sufficient, I'm hoping someone can point me in such a direction so that I will know what does constitute a proper validation.

Buffering a client-side file download

I have a file which is split up into multiple parts on the server side. The complete file is huge, it can be 10 or more gigabytes in size (that is the reason for splitting it in the first place).
The file is in a specific format, and it has to be processed on the client side before being downloaded.
Now, I know that I can download into a Blob to the client side, do the processing, then download Blobs from there with this approach: JavaScript blob filename without link
The problem here is that I would need to construct a single huge blob from all the file parts on the client side, which I do not want, because it will probably exceed RAM limitations rather quickly.
I would like to download each part of the file individually and then process it and download the "partial" blob. That means that I would need to start a download and then piece by piece add blobs to it until the download is complete.
Is there any possibility of doing this? How? I know that mega.co.nz does something similar with file downloads where they process the file on the client side first (for decryption). Are they using such techniques?
You can save the downloaded parts to localStorage. You will have to serialize each part into a string first; then you can call localStorage.setItem. Your code might look like this:
localStorage.setItem('download-part-' + chunkIndex, chunkDataAsString);
chunkDataAsString = ''; // let the garbage collector collect the large string

How can I detect image specs clientside with javascript

I want to validate image file uploads client side.
T
here will be server side validation, too, which is working already with image magick.
I would like to reproduce this on the client side before uploading (since the files will be quite large and prerequisits for the image files are very restricted, it could save the user much pain if the validation takes place in the browser before the upload process)
Allowed files would be:
JPEG
EPS
TIFF
I need to detect:
Color Space (CMYK / RGB)
Size (width x height) // this one is easy - on JPEGs, but how about TIFF and EPS?
Resolution (dpi)
The main problem is detecting color space and handling the non-JPG formats. Is there something like ImageMagick's "identify" for javascript or do you have any other ideas...?!
Take a look at this. It uses HTML5 APIs, but it looks like what you are looking for.

Get file size (in bytes) on client side

I make multiple file uploading project, (Server language is PHP)
Especially, I need that before uploading, on client side, get files size in bytes.
what is today best cross browser solution/plugin for this?
I find SWFUpload, may be exists better solution? or use this SWFUpload?
In HTML5 a file drag & drop event creates a File object which has a .size property.
Look in ev.dataTransfer for the list of File objects.

Including base64 gzipped stylesheets/images in javascript?

I know you can include css and images, among other file types, which have been stored in base64 form within a javascript file. However, those are decently huge... and gzipped, they shrink down a LOT, even with the ~33% overhead from base64 encoding.
Non-gzipped, images are data:image/gif;base64, data:image/jpeg, data:image/png, and css is data:text/css;base64. What mime type can/should I be using, then, to include css or image data URIs which are gzipped? (Or if gzip+base64 can't work, is there any other compression I can do to bring down the string's size, while still keeping the data stored within the javascript?)
..edit..
I think the question is being misunderstood. I am not asking if I should include gzipped base64 strings within javascript. Yes, I know it's best, in most cases, to gzip the javascript and other files on the server end. But that is not applicable for a userscript; a userscript has no server, and consists of only a single file. Firefox allows a #require directive, but Opera and Chrome do not, and local file security issues come into play with loading any local files. Thus anything needed by the script has to be either: 1) on the web (slow) or 2) embedded in the userscript (big).
Now this question assumes that big is preferable to slow, but that big does not have to mean we totally ignore just how big; if it can be smaller, that's an improvement.
So assuming that a base64 string is embedded in javascript, the question is how to make it into something meaningful.
Either:
1) atob() can convert raw base64-encoded gzip to raw gzip within javascript. (atob does not need to know the mediatype). The question then would be how to decompress that raw gzipped css or image file so that the resulting output can be fed into the document.
or 2) given the proper mediatype, browsers at least theoretically (per the datauri RFC) should be able to load any file directly from a datauri. "" is sufficient to load a non-gzipped css stylesheet. The question here would be what link type attribute and datauri mediatype combination should work (and which browsers would it work for)? Preferably, for a userscript, this would be a combination that works in Opera, FF, and Chrome.
In HTTP, compression is most often only applied for transmission to reduce the payload that is to be transmitted. This is done by the Content-Encoding header field.
But the data URL scheme is very limited and you can only specify the media type:
dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
Although you could use a multipart message, most user agents don’t support them in data URLs. It would also be questionable whether the additional data to describe such a multipart message wouldn’t be more than the data you safe by compressing the actual payload.
So compressing the data in a data URL is possible in theory but impracticable. It is better to simply compress the whole document the data URL is embedded in.

Categories

Resources