Jump to content

How to Encrypt Files when uploading with uniFileUpload or uniFileUploadButton from Client to Server ?


irigsoft

Recommended Posts

Hello,

is it possible to encrypt the files (images, text files or other kind) when the client uses uniFileUpload (uniFileUploadButton)?

I need to protect the server from possible attacks by uploading a dangerous file:

1. encrypting files uploaded by a client with generating a hash for the file, (from unigui code or javascript code on Client side)

         - send hash to server (SHA-1,Sha-2,HMAC)

          - send encrypted file to server

    , and server will check if file hash (generated on Client side) is equal to file hash (generated from server) when server get file

3. disable autorun scripts masquerading as images or other file types

     - if the file is encrypted, this will disable the execution of malicious code from the file

 

Any help is welcome.

Link to comment
Share on other sites

If the file is encrypted (with a password specified by me on the server side), no script will be able to run after encryption.
Take the following example.
A client connected to a fake router (man-in-the-middle attack, using rouge router attack) tries to upload a photo to the database through the application.
This file is intercepted by an attacker and replaced with another containing malicious code.
The idea here is to perform two actions:
1. to send from the client side a Hash of the file selected by the client, and this Hash is encrypted with a password taken from the server
2. The file itself is encrypted with the same or a different password.

item 1 - will enable the server to check if there is a change to the file during its transfer
item 2 will guarantee that even if we are late (or we are lied to by the attacker) the file falling into the database or on the server will not be able to execute itself.

 

We adhere to security practices from The Cybersecurity Cube (McCumber cube): https://en.wikipedia.org/wiki/McCumber_cube
It provides a useful way to think about protecting data. The cube reminds us of what the task of protecting data entails, including the three dimensons of information security.

 

Protect data in states (Data in transit, Data at rest or in storage, Data in process )

Secure Data in Process: "Data in transit involves sending information from one device to another. Protecting data in transit poses challenges. There are numerous ways to transmit information between devices. Wireless networks are often deployed to provide easy network access to corporate users. Those users then access corporate data."

 

Link to comment
Share on other sites

Just now, Sherzod said:

Isn't it easier to use https?

Unfortunately, it is not enough.


I would like to secure the server, and HTTPS is not a sufficient solution for this.


However, it is possible that the client is the attacker himself and is trying to upload a dangerous file to the server.
For this reason, the verification will be performed in several steps as I described.
HTTPS is not a panacea unfortunately.

Link to comment
Share on other sites

17 minutes ago, Sherzod said:

Thanks.

So no way using unigui  (is not integrated into uniFileUpload) ?

Can we apply some of this:

https://github.com/kartik-v/bootstrap-fileinput/issues/1630

https://codepen.io/jipd/pen/KMLMXe

https://stackoverflow.com/questions/32341782/javascript-encrypted-file-upload

 

On uniFileUpload is possible OnCompleted event, but this is after file is uploaded, is it possible there to integrate some encryptions or is too late ?

Link to comment
Share on other sites

8 minutes ago, Sherzod said:

This post may help you...

 

Thanks, but how.

I don't see any code that can help me to add encryption.

is it possible to add it here :

MainForm.Script add:

Ext.form.field.File.override(
     {onFileChange: function() {
       this.lastValue = null; // force change event to get fired even if the user selects a file with the same name
       Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value.replace(/C:\\fakepath\\/g, ''));
       }
     }
)
Link to comment
Share on other sites

Thanks,

1. I will try this: "there is a way to use javascript or ajax to encrypt file uploads. You can use standard Web APIs that have built-in native support in browsers: Use the standard File API and WebCrypto API to get the file from your filesystem and actually encrypt it—along with the Indexed Database API (indexedDB) (if you want) to store the encrypted file on the client side in the browser. A good simple example with working code is at Upload a file, encrypt it, calculate the hash and store the results using indexedDB."

from here: https://stackoverflow.com/questions/32341782/javascript-encrypted-file-upload

 

or

2.  this: https://stackoverflow.com/questions/25593574/progressive-upload-and-encryption-with-cryptojs

or

3. https://codepen.io/jipd/pen/KMLMXe

 

Some help how to integrate point 1, 2 or 3 in unigui would be helpful.

Link to comment
Share on other sites

Hi,

I try to implement this code to encode UploadFile but here i have a problem:

https://gist.github.com/Ayms/6451926

code:

1. how to replace this with uniFileUpload -   <input type="file" onsubmit="process_upload">

2.How to add this code on MyForm.Script and make it work on FileUpload:

var workerjs=' \
  onmessage=function(evt) { \
		var encrypt=crypto.workersubtle.encrypt({name:"AES-CBC",iv:new Uint8Array(16)},evt.data[0]); \
		var buffer=evt.data[1]; \
		var block=XXX; \
		while (buffer.length) { \
			encrypt.process(buffer.subarray(0,block)).done(function(result) { \
				postMessage(result) \
			}); \
			buffer=buffer.subarray(Math.min(buffer.length,block)); \
		}; \
		encrypt.finish().done(function(result) { \
			postMessage([result]); \
		}); \
	} \
';

var process_upload=function() {
	var file=this.files[0];
	var process=function(key) {
		var reader=new FileReader();
		var readed=function() {
			var request={};
			var file_enc=[];
			var size=reader.result.byteLength;
			var tsize=0;
			var worker=new Worker(URL.createObjectURL(new Blob([workerjs])));
			var h=crypto.subtle.digest('SHA-256'); 
			worker.onmessage=function(evt) {
				var res=(evt.data instanceof Array)?evt.data[0]:evt.data;
				tsize +=res.length;//display a progress bar (tsize/size)*100%
				file_enc.push(res);
				h.process(res).then(function() {
					if (evt.data instanceof Array) { //end
						request.blob=new Blob(file_enc,{type:'application/octet-binary'});
						request.type=file.type;
						this.finish(res).done(function(result) {
							request.file_hash=result;
							store_DB(request);
						});
					};
				});
			};
			worker.postMessage([key,new Uint8Array(reader.result)]);
		};
		reader.addEventListener("loadend",readed,false);
		reader.readAsArrayBuffer(file);
	};

//3.How to add myKey from Server like Variable and replace it here - MyKeyVar = 00112233445566778899aabbccddeeff
	crypto.importKey("raw",TextToArrayBufferView('00112233445566778899aabbccddeeff'),'AES-CBC',false,['encrypt','decrypt']).done(function(result) {process(result)});
};

var open_db=function() {
	var db=demoDB.db;
	return db.transaction(['encrypted_files'],'readwrite').objectStore('encrypted_files');
};

var store_DB=function(request) {
	var objectStore=open_db();
	objectStore.put({hash:request.file_hash,type:request.type,blob:request.blob});
};

var demoDB=indexedDB.open('demo',1);

demoDB.onupgradeneeded=function(evt) {
	var db=evt.target.result;
	db.createObjectStore('encrypted_files',{keyPath:'hash'});
};

demoDB.onsuccess=function (evt) {
	demoDB.db=evt.target.result;
};

4. I use MultiFileUpload on attached Example - code is added on MainForm.Script but Form not loading.

Encrypt_FileUpload - Multiple.zip

Link to comment
Share on other sites

I've been working on this and hit a problem:

my script:

1. Limit uniFileUpload.Filter to only list of available file extentions

2. rename the uploaded file and replace all special characters from the name

3. create a hash of the file

4. Encrypt the file

5. uploading an encrypted file to the server

How to execute point 1 to extentions like - jpg,jpeg,xml,txt,csv,xls. 

however, in the code created in point 2 to replace characters in MainForm.Script, the file list is not populated with replaced (or original) file names, and of course I get an error when trying to upload.

I am trying to replace characters from this filename like this : IMG_[20]23{}1205_%09#21@30+.jpg

 

FileUpload - Multiple.zip

Link to comment
Share on other sites

"I need to protect the server from possible attacks by uploading a dangerous file"

If you control the upload, the transfer protocol, the decoding, the local to save the file, the file type, server side security, storage rights... in Windows ?

Gosh ! that's a hack of security. Sale it to Amazon, Azure...

Just save it where it can be directly downloaded/run/read or called by the browser. Otherwise your server is already compromised. Or save it in raw format at server folder following  these rules.. simpler.
 

Edited by Fred Montier
typos
Link to comment
Share on other sites

9 hours ago, Fred Montier said:

"I need to protect the server from possible attacks by uploading a dangerous file"

If you control the upload, the transfer protocol, the decoding, the local to save the file, the file type, server side security, storage rights... in Windows ?

Gosh ! that's a hack of security. Sale it to Amazon, Azure...

Just save it where it can be directly downloaded/run/read or called by the browser. Otherwise your server is already compromised. Or save it in raw format at server folder following  these rules.. simpler.
 

Hello and Merry Christmas to all.

Yes, I prefer it to be "simpler", but I work with companies and their security engineers say, "Hey, if you allow the user to upload and download files, then you need to protect them!"

Yes, I know there are many issues with OS provisioning and just one software that takes care of that is not enough, but if I want to sell my software to these companies then I have to work according to what they want, I don't have another choice.

There are many other things in my action plan that I have done for my clients, but I try to add more of the security best practices as recommended by those more experienced than me:

https://www.opswat.com/blog/file-upload-protection-best-practices

https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload

https://uploadcare.com/blog/secure-file-upload/

https://learn.microsoft.com/en-us/iis/get-started/planning-for-security/secure-content-in-iis-through-file-system-acls

https://doc.sitecore.com/xp/en/developers/82/sitecore-experience-platform/secure-the-file-upload-functionality.html

https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API/Non-cryptographic_uses_of_subtle_crypto


 

Link to comment
Share on other sites

On 12/17/2023 at 7:10 PM, Sherzod said:

Yes, this code is not what you want. But, here I wanted to point you to an event where you can process a file...

Hi, I'm trying to override (as you suggested on MainForm.Script)

Ext.form.field.File.override({
   onFileChange: function() {
       this.lastValue = null; // force change event to get fired even if the user selects a file with the same name
       Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value.replace(/C:\\fakepath\\/g, ''));

       var fi = this.fileInputEl.dom.files; 
       for (var i = 0; i < fi.length; i++) {       
          var file = fi[i];          
alert ('Type: ' + file.type);
 
       };//for     


  }//end - onFileChange
});//end - Ext.form.field.File.override
                  

I am using uniFileUpload, but this way the list with selected files is not populated and none of the files are uploaded.

Link to comment
Share on other sites

19 hours ago, irigsoft said:

Hi, I'm trying to override (as you suggested on MainForm.Script)

Ext.form.field.File.override({
   onFileChange: function() {
       this.lastValue = null; // force change event to get fired even if the user selects a file with the same name
       Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value.replace(/C:\\fakepath\\/g, ''));

       var fi = this.fileInputEl.dom.files; 
       for (var i = 0; i < fi.length; i++) {       
          var file = fi[i];          
alert ('Type: ' + file.type);
 
       };//for     


  }//end - onFileChange
});//end - Ext.form.field.File.override
                  

I am using uniFileUpload, but this way the list with selected files is not populated and none of the files are uploaded.

Exactly this code works.


But I see that you have additional codes there. I will try to analyze...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...