Restrictions on Js file upload type of Web front end (judged according to file header information)

Posted by ridiculous on Fri, 31 Dec 2021 15:24:28 +0100

preface

In the process of Web project development, the file upload function is almost essential. Many times, when we upload files, especially when we open the file upload function to ordinary users, we generally need to limit the format of uploaded files to prevent bad users and hackers from uploading virus script files to the server, Common file formats are limited as follows.

1. This is restricted by the accept attribute of the input tag

We can use the accept attribute of the input file tag in HTML5 to specify the visible file type format (any type by default) when selecting the file to upload according to our own needs.

Example code:

<input type="file" id="oFile" name="myFiles" accept=".doc, .docx, .xls, .txt" onchange="upFile(event)" />

2. Get the file of the uploaded file through JS Type or file Name attribute

In JS, you can obtain the relevant attributes of the uploaded file through the file object in the upload event.

Example code:

function upFile(event) {
	const [ file ] = event.target.files || event.dataTransfer.files || this.file.files;
	
	console.dir(file); // File object
	console.log(file.name); // File name  
	console.log(file.type); // file type
    console.log(file.size); // file size
	
	// Make simple restrictions on file types: for example, only JPG, PNG, GIF can be uploaded
	if(!file.type && /\.(?:jpg|png|gif)$/.test(file.name)) ){ 
	    alert('Sorry: the uploaded picture format can only be: jpg, png, gif Format!'); 
    	return false; 
    } 
}

The above two methods are the most common methods to limit the file upload type. However, if we simply restrict by intercepting the file suffix (extension) and file type, it is very easy to be cracked. For example, if the user wants to rename the file suffix (extension) and the uploaded file type specified by you, it bypasses your restriction, You can complete the upload.

At this point: we judge the real format of the file according to the header information of the file.

3. Get the header information of the uploaded file through the FileReader method of JS for restriction

In JS, restrictions are made by reading the hexadecimal header information of the file, because the header information of the same type of file is the same. Even if the user modifies the suffix (extension) of the file, the header information of the file will not change.

Example code:

// Read the binary data of the file and convert it to hexadecimal
function fileReader (blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsBinaryString(blob);
    reader.onload = (ret) => {
      const res = reader.result.split('').map((o) => o.charCodeAt().toString(16).padStart(2, '0'));
      resolve(res.join(' ').toUpperCase());
    },
    reader.onerror = (err) => {
      reject(err);
    };
  });
};

// png format
async function isPng(file) {
  return (await fileReader(file.slice(0, 8))) == "89 50 4E 47 0D 0A 1A 0A";
};

// jpg format
async function isJpg(file) {
  const start = await fileReader(file.slice(0, 2));
  const end = await fileReader(file.slice(-2, file.size));
  return "FF D8" == start && "FF D9" == end;
};

// gif format
async function isGif(file) {
  const ret = await fileReader(file.slice(0, 6));
  return "47 49 46 38 39 61" == ret || "47 49 46 38 37 61" == ret;
};

async function upFile(event) {
	const [ file ] = event.target.files || event.dataTransfer.files || this.file.files;
	
	console.dir(file); // File object
	console.log(file.name); // File name  
	console.log(file.type); // file type
    console.log(file.size); // file size
	
	// Judge and limit according to the file header information: for example, only png format can be uploaded
	if(!await isPng(file)){ 
	    alert('Sorry: the uploaded picture format can only be: png Format!'); 
    	return false; 
    }
}

4. Restrictions are made through a third-party file type toolkit

The file type toolkit is also encapsulated with Js. Its principle is the same as the third method above. It supports dozens of file types, which can almost meet our daily development needs.

Npm address: https://www.npmjs.com/package/file-type

Topics: Javascript Front-end