Art*_*nyi 6 .net .net-core asp.net-core asp.net-core-webapi
互联网上围绕这个问题有很多讨论。 示例 1 示例 2 但我没有找到 .net core 的任何答案地址。
那么, 有谁知道检查文件格式签名的正确方法,以防止用户上传伪装的文件?
Microsoft 有一篇关于文件上传的优秀文章,强烈推荐阅读 - 请参阅: https: //learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads ?view=aspnetcore-5.0
本文涵盖的主题包括检查文件签名、允许的扩展名、将扩展名与文件签名匹配、重命名文件、存储文件等。
在那篇文章中,他们还解释了如何检查文件签名,这与您已经提供的答案非常相似。然而,它更深入一些,一些文件类型可以有多个签名:
FileHelper.cs(完整文件位于:https://github.com/dotnet/AspNetCore.Docs/blob/master/aspnetcore/mvc/models/file-uploads/samples/3.x/SampleApp/Utilities/FileHelpers.cs) :
private static readonly Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
{
{ ".gif", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } },
{ ".png", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
{ ".jpeg", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 },
}
},
{ ".jpg", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 },
}
},
{ ".zip", new List<byte[]>
{
new byte[] { 0x50, 0x4B, 0x03, 0x04 },
new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x45 },
new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
new byte[] { 0x50, 0x4B, 0x05, 0x06 },
new byte[] { 0x50, 0x4B, 0x07, 0x08 },
new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 },
}
},
};
// File signature check
// --------------------
// With the file signatures provided in the _fileSignature
// dictionary, the following code tests the input content's
// file signature.
var signatures = _fileSignature[ext];
var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));
return signatures.Any(signature =>
headerBytes.Take(signature.Length).SequenceEqual(signature));
Run Code Online (Sandbox Code Playgroud)
有关更多签名 - 请参阅https://www.filesignatures.net/和https://www.garykessler.net/library/file_sigs.html
此外,您可以使用十六进制文件查看器自行轻松检查任何文件的签名。例如,在 Windows 10 中,使用 PowerShell,您只需在 PowerShell 提示符中编写以下命令即可 ( https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/format-h ex?view=powershell -7.1):
PS> format-hex c:\myfile.gif
Run Code Online (Sandbox Code Playgroud)
翻译成 C# 可以得到:
new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 } // 'GIF89a'
new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 } // 'GIF87a'
new byte[] { 0x47, 0x49, 0x46, 0x38 } // 'GIF8' (detect above two signatures by only looking at the first four bytes)
Run Code Online (Sandbox Code Playgroud)
我没有找到任何特定于 .net core 的“lib/nuget/class”,这可能会让我们的生活更轻松。因此,我回到了一种常见的方法,即将字节文件头与示例进行比较。
private readonly Dictionary<string, byte[]> _mimeTypes = new Dictionary<string, byte[]>
{
{"image/jpeg", new byte[] {255, 216, 255}},
{"image/jpg", new byte[] {255, 216, 255}},
{"image/pjpeg", new byte[] {255, 216, 255}},
{"image/apng", new byte[] {137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82}},
{"image/png", new byte[] {137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82}},
{"image/bmp", new byte[] {66, 77}},
{"image/gif", new byte[] {71, 73, 70, 56}},
};
private bool ValidateMimeType(byte[] file, string contentType)
{
var imageType = _mimeTypes.SingleOrDefault(x => x.Key.Equals(contentType));
return file.Take(imageType.Value.Length).SequenceEqual(imageType.Value);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5311 次 |
最近记录: |