当前位置: 首页 > news >正文

ASP.NET 上传文件安全检测方案

一、前端初步过滤(防误操作)

<!-- HTML部分 --><input type="file" id="fileUpload" accept=".jpg,.png,.pdf,.docx" /><button onclick="validateFile()">上传</button><script>functionvalidateFile(){const file = document.getElementById('fileUpload').files[0];if (!file) return alert('请选择文件');// 检查文件扩展名const allowedExtensions = /(\.jpg|\.png|\.pdf|\.docx)$/i;if (!allowedExtensions.test(file.name)){ alert('不允许的文件类型'); return false; }// 检查文件大小(示例:限制20MB)if (file.size > 20 * 1024 * 1024){ alert('文件超过20MB'); return false; }// 提交表单document.getElementById('uploadForm').submit();}</script>

二、后端深度验证(核心防御)

// 1. 验证文件扩展名(双重验证,防止绕过前端)

// 2. 验证MIME类型(检查Content-Type头)

// 3. 验证文件内容(魔数检测)

// 4. 扫描文件是否包含恶意代码(示例:检查HTML文件中的脚本标签)

// 5. 保存文件到安全位置(禁用执行权限)

// ASP.NET MVC控制器示例[HttpPost][ValidateAntiForgeryToken]public ActionResult Upload(HttpPostedFileBase file){if (file == null || file.ContentLength == 0)return Json(new { success = false, message = "请选择文件" });try{// 1. 验证文件扩展名(双重验证,防止绕过前端)var allowedExtensions = new[] { ".jpg", ".png", ".pdf", ".docx" };var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();if (!allowedExtensions.Contains(fileExtension))return Json(new { success = false, message = "文件类型不允许" });// 2. 验证MIME类型(检查Content-Type头)if (!IsValidMimeType(file.ContentType, fileExtension))return Json(new { success = false, message = "文件类型不匹配" });// 3. 验证文件内容(魔数检测)if (!IsValidFileContent(file.InputStream, fileExtension))return Json(new { success = false, message = "文件内容异常" });// 4. 扫描文件是否包含恶意代码(示例:检查HTML文件中的脚本标签)if (fileExtension == ".html" && ContainsMaliciousCode(file.InputStream))return Json(new { success = false, message = "文件包含恶意代码" });// 5. 保存文件到安全位置(禁用执行权限)var fileName = Guid.NewGuid().ToString() + fileExtension;var filePath = Path.Combine(Server.MapPath("~/Uploads/"), fileName);file.SaveAs(filePath);return Json(new { success = true, message = "上传成功" });}catch (Exception ex){// 记录详细日志(包含文件名、大小、时间戳等)Logger.Error($"文件上传失败: {ex.Message}", ex);return Json(new { success = false, message = "上传过程中发生错误" });}}// 验证MIME类型private bool IsValidMimeType(string contentType, string fileExtension){var allowedMimeTypes = new Dictionary<string, string[]>{{ ".jpg", new[] { "image/jpeg", "image/pjpeg" } },{ ".png", new[] { "image/png" } },{ ".pdf", new[] { "application/pdf" } },{ ".docx", new[] { "application/vnd.openxmlformats-officedocument.wordprocessingml.document" } }};if (!allowedMimeTypes.ContainsKey(fileExtension))return false;return allowedMimeTypes[fileExtension].Contains(contentType);}// 验证文件内容(魔数检测)private bool IsValidFileContent(Stream stream, string fileExtension){// 重置流位置stream.Position = 0;// 读取文件前几个字节(魔数)var buffer = new byte[8];stream.Read(buffer, 0, buffer.Length);stream.Position = 0; // 重置流位置供后续使用// 根据文件类型检查魔数switch (fileExtension){case ".jpg":// JPEG魔数: FF D8 FFreturn buffer[0] == 0xFF && buffer[1] == 0xD8 && buffer[2] == 0xFF;case ".png":// PNG魔数: 89 50 4E 47 0D 0A 1A 0Areturn buffer[0] == 0x89 && buffer[1] == 0x50 && buffer[2] == 0x4E && buffer[3] == 0x47 && buffer[4] == 0x0D && buffer[5] == 0x0A &&                   buffer[6] == 0x1A && buffer[7] == 0x0A;    case ".pdf":// PDF魔数: 25 50 44 46return buffer[0] == 0x25 && buffer[1] == 0x50 && buffer[2] == 0x44 && buffer[3] == 0x46;default:// 其他类型可以添加更多检查return true;}}// 检查文件是否包含恶意代码(示例:HTML文件)private bool ContainsMaliciousCode(Stream stream){using (var reader = new StreamReader(stream)){var content = reader.ReadToEnd();stream.Position = 0; // 重置流位置// 检测常见的恶意代码模式//在这里增加被攻击的恶意代码var maliciousPatterns = new[] {@"<script\s*[^>]*>",@"vbscript:",@"onerror\s*=",@"<iframe\s*[^>]*>"};return maliciousPatterns.Any(pattern =>Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase));}}@"<?xml", // XML注入@"<!DOCTYPE", // XXE攻击@"<script", // 脚本注入@"<img", // 图片标签注入@"<iframe", // iframe注入@"<object", // object标签@"<embed", // embed标签@"<applet", // applet标签@"<form", // form标签@"<input", // input标签@"<link", // link标签@"<style", // style标签@"<svg", // SVG注入@"<math", // MathML注入@"onerror", // 事件处理器@"onload", // 事件处理器@"javascript:", // JS协议@"data:text/html", // data协议@"base64,", // base64编码@"eval(", // eval函数@"expression(", // CSS表达式@"alert(", // alert函数@"document.cookie", // 访问cookie@"window.location", // 重定向@"window.open", // 弹窗@"fetch(", // fetch API@"XMLHttpRequest", // AJAX@"ActiveXObject", // ActiveX@"<meta", // meta标签@"<body", // body标签@"<head", // head标签@"<title", // title标签@"<audio", // audio标签@"<video", // video标签@"<source", // source标签@"<track", // track标签@"<marquee", // marquee标签@"<blink", // blink标签@"<bgsound", // bgsound标签@"<frame", // frame标签@"<frameset", // frameset标签@"<noscript", // noscript标签@"<plaintext", // plaintext标签@"<xss", // xss标签@"vbscript:", // vbscript协议@"mocha:", // mocha协议@"livescript:", // livescript协议@"<!--", // 注释@"-->", // 注释@"<%=", // ASP/模板注入@"<?php", // PHP代码// @"<%!", // JSP/模板注入@"<%#", // ASP.NET模板注入@"<%$", // ASP.NET模板注入@"<%:", // ASP.NET模板注入@"<%?", // 模板注入@"<%--", // 注释@"<%>", // 模板@"<c:", // JSTL标签@"<jsp:", // JSP标签@"<s:", // Struts标签// @"<%@", // 指令// @"<#", // Freemarker@"#include", // SSI@"system(", // 系统命令@"exec(", // 系统命令@"passthru(", // 系统命令@"shell_exec(", // 系统命令@"popen(", // 系统命令@"proc_open(", // 系统命令@"require", // PHP@"include", // PHP@"require_once", // PHP@"include_once", // PHP@"import", // Python/JS// @"from", // Python@"os.system", // Python@"subprocess", // Python@"rm -rf", // Linux命令@"del ", // Windows命令@"request",@"eval",@"cmd"

http://www.dtcms.com/a/329030.html

相关文章:

  • 怎么使用python查看网页源代码
  • FreeRTOS创建多线程详解
  • 基于微信小程序的工作日报管理系统/基于asp.net的工作日报管理系统
  • USB批量传输数据为端点最大数据包(比如512字节)整数倍时接收端收不到数据
  • Linux系统文件完整性检查工具AIDE在生产环境中推送钉钉告警
  • 音视频处理新纪元:12款AI模型的语音转录和视频理解能力横评
  • MySQL 到 ClickHouse 明细分析链路改造:数据校验、补偿与延迟治理
  • 前端css学习笔记4:常用样式设置
  • 2025盛夏AI热浪:八大技术浪潮重构数字未来
  • RC4算法实现
  • 前后端分离项目在云服务器的部署
  • java实现sql解析器 JSQLParser
  • 16-docker的容器监控方案-prometheus实战篇
  • 30 HTB Soccer 机器 - 容易
  • 【Android】四种不同类型的ViewHolder的xml布局
  • 双写一致性问题如何解决?
  • Python 元类基础:从理解到应用的深度解析
  • 机器翻译:学习率调度详解
  • 小电视视频内容获取GUI工具
  • 长篇音频制作(小说自动配音)完整教程
  • 嵌入式 - linux软件编程: 目录 IO及时间相关的函数接口
  • 《Python学习之基础语法1:从零开始的编程之旅》
  • Verilog功能模块--SPI主机和从机(02)--SPI主机设计思路与代码解析
  • 电商项目微服务架构拆分实战
  • 使用TexLive与VScode排版论文
  • 内容索引之word转md工具 - markitdown
  • 华为 HCIE 大数据认证中 Linux 命令行的运用及价值
  • 【linux】--U盘挂载
  • 【CV 目标检测】③——目标检测方法
  • 2025_07_安装Jmeter,创建一个登录请求