| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- using System.IO.Compression;
- using System.Text;
- namespace Admin.NET.Plugin.AiDOP.DataPlatform.FileImport;
- public static class MdpFileImportSecurity
- {
- public const long MaxBytes = 20 * 1024 * 1024;
- public const int MaxRows = 50000;
- public const int MaxColumns = 80;
- public const int MaxCellChars = 2000;
- public static void EnsureXlsx(string fileName, long length, Stream stream)
- {
- if (length <= 0)
- throw new InvalidOperationException("空文件");
- if (length > MaxBytes)
- throw new InvalidOperationException("文件超过 20MB");
- var ext = Path.GetExtension(fileName);
- if (!string.Equals(ext, ".xlsx", StringComparison.OrdinalIgnoreCase))
- throw new InvalidOperationException("仅支持 .xlsx");
- if (fileName.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".."))
- throw new InvalidOperationException("不允许宏文件或路径穿越");
- Span<byte> header = stackalloc byte[4];
- var read = stream.Read(header);
- if (stream.CanSeek) stream.Position = 0;
- if (read < 4 || header[0] != (byte)'P' || header[1] != (byte)'K')
- throw new InvalidOperationException("不是合法 xlsx(ZIP)文件");
- if (stream.CanSeek)
- {
- using var zip = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: true, Encoding.UTF8);
- if (zip.Entries.Any(e => e.FullName.Contains("vbaProject", StringComparison.OrdinalIgnoreCase)
- || e.FullName.Contains("externalLink", StringComparison.OrdinalIgnoreCase)))
- throw new InvalidOperationException("拒绝含宏或外部链接的工作簿");
- stream.Position = 0;
- }
- }
- public static void EnsureCell(string? value)
- {
- if (value != null && value.Length > MaxCellChars)
- throw new InvalidOperationException($"单元格超过 {MaxCellChars} 字符");
- if (value != null && value.StartsWith('='))
- throw new InvalidOperationException("不允许公式单元格");
- }
- public static void StripClientTenant(IDictionary<string, object?> row)
- {
- var keys = row.Keys.Where(k => k.Equals("tenant_id", StringComparison.OrdinalIgnoreCase)
- || k.Equals("TenantId", StringComparison.OrdinalIgnoreCase)).ToList();
- foreach (var k in keys)
- row.Remove(k);
- }
- }
|