File upload in web application always open gates for malicious activity to perform on server if not validate properly. We are already allowed only to upload files with some predefined extensions like PDF, DOC,.. etc. But this can not prevent some evil user to upload an executable file after renaming it to PDF or JPEG.
So first of all I will explain what are "magic numbers", and then I will show how we handle them in C#.
Below is a sample code for validating file upload using magic check and simple file extension.
private Boolean validateFileUpload()
{
/*
pdf 25-50-44-46
png 89-50-4E-47
gif 47 49 46 38
jpg FF-D8-FF-E1
jpeg FF-D8-FF-E0*/
string fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
string[] path = { ".jpg", ".jpeg", ".gif", ".png", ".pdf" };
string[] magicNumbers = {"25-50-44-46","89-50-4E-47","47 49 46 38","FF-D8-FF-E1","FF-D8-FF-E0"};
string ext = Path.GetExtension(fileName).ToString().ToLower();
string contenttype = FileUpload1.PostedFile.ContentType;
string content = FileUpload1.PostedFile.ContentType.ToString().ToLower();
string data_as_hex;
string magicCheck=string.Empty;
BinaryReader chkBinary;
Byte[] chkbytes;
bool extValidation = false;
if (!string.IsNullOrWhiteSpace(fileName))
{
//check magic numbers
Stream checkStream = FileUpload1.PostedFile.InputStream;
if (checkStream.Length > 0)
{
chkBinary = new BinaryReader(checkStream);
chkbytes = chkBinary.ReadBytes(0x10);
data_as_hex = BitConverter.ToString(chkbytes);
magicCheck = data_as_hex.Substring(0, 11);
}
for (int i = 0; i < magicNumbers.Length; i++)
{
if (magicCheck.Equals(magicNumbers[i]) )
{
extValidation = true;
break;
}
}
if (!extValidation)
{
//ltrDocError.Text = Convert.ToString(GetLocalResourceObject("Inavlidfileupload"));
return false;
}
//check path
for (int i = 0; i < path.Length; i++)
{
if (ext.Equals(path[i]))
{
extValidation = true;
break;
}
}
if (!extValidation)
{
//ltrDocError.Text = Convert.ToString(GetLocalResourceObject("Inavlidfileupload"));
return false;
}
//else if (dtgDocUpload.Rows.Count >= 1)
//{
// ltrDocError.Text = Convert.ToString(GetLocalResourceObject("errDocCount"));
// return false;
//}
else
{
return true;
}
}
else {
return false;
}
}
No comments:
Post a Comment