使 ASP.Net 文件上传安全
Posted
技术标签:
【中文标题】使 ASP.Net 文件上传安全【英文标题】:make ASP.Net file upload secure 【发布时间】:2018-03-28 15:14:33 【问题描述】:我正在创建一个带有文件上传控件的 ASP.Net 表单,然后它将表单和文件的详细信息通过电子邮件发送给另一个管理员。我想确保这个安全(对于服务器和收件人)。附件应该是简历,所以我将其限制为典型的文本文档。
据我所知,最好的办法是检查文件扩展名或 MIME 类型是否属于这种类型,并对照“幻数”检查以验证扩展名是否未更改。我不太关心如何去做,但想知道这是否真的足够。
我也很乐意使用第三方产品来解决这个问题,我看过几个:
blueimp jQuery 文件上传 http://blueimp.github.io/jQuery-File-Upload/
和可爱的 ajaxuploader http://ajaxuploader.com/Demo/
但是 blueimp 一个似乎仍然需要自定义服务器验证(我猜它只是 jQuery,它只处理客户端验证)并且 .net 一个检查 MIME 类型与扩展名匹配,但我认为 MIME 类型无论如何都遵循扩展名.
所以,
当文件作为附件添加但未保存时,我是否需要担心服务器安全? 是否有一个插件或控件可以很好地处理这个问题? 如果我自己需要为服务器验证实现某些东西,是否将 MIME 类型与“幻数”相匹配就足够了?
我确信没有什么是 100% 防弹的,但文件上传是很常见的事情,我认为大多数实现都“足够安全” - 但是如何!?
如果相关,这是我目前的基本代码
<p>Please attach your CV here</p>
<asp:FileUpload ID="fileUploader" runat="server" />
并在提交时
MailMessage message = new MailMessage();
if (fileUploader.HasFile)
try
if (fileUploader.PostedFile.ContentType == "text")
// check magic numbers indicate same content type... if()
if (fileUploader.PostedFile.ContentLength < 102400)
string fileName = System.IO.Path.GetFileName(fileUploader.PostedFile.FileName);
message.Attachments.Add(new Attachment(fileUploader.PostedFile.InputStream, fileName));
else
// show a message saying the file is too large
else
// show a message saying the file is not a text based document
catch (Exception ex)
// display ex.Message;
【问题讨论】:
“当文件作为附件添加但未保存时,我是否需要担心服务器安全?” 不明白您的意思?什么是“得救”?关于过程的哪一部分“安全”?如果不满足条件,您是否尝试从<input type="file">
.files
属性中删除文件对象?
@guest271314 用户正在上传文件,并将其作为附件添加到随后发送的电子邮件中。据我所知,这不会导致文件保存在服务器上,我猜它最终会保存在邮件服务器上。收件人可能会保存它,但我的意思是它没有保存在服务器上。
“收件人可能会保存它,但我的意思是它没有保存在服务器上。”您对所描述的过程有什么担忧?
@guest271314 虽然我很担心有人危言耸听推销东西:acunetix.com/websitesecurity/upload-forms-threat
@GramThanos 一开始我真的很喜欢这个想法,但我认为它不能解决嵌入式代码或宏等问题。 - 该文件只会与服务器上的更多交互以压缩它和收件人在解压缩后仍然会得到相同的文件。老实说,我认为我的问题是无知和偏执狂的可怕混合!我的解决方案是采取务实的方法,采取一些合理的措施,并了解我们的基础设施有措施在上游进一步保护自己——我很快就会写出更多细节。聪明的建议,谢谢!
【参考方案1】:
服务器永远不可能 100% 安全,但我们应该尽最大努力将事故风险降至最低。在这一点上我应该说我不是专家,我只是一名计算机科学专业的学生。所以,这是我在这种情况下会遵循的一种方法。请评论您可以提供的任何其他提示。
一般而言,要获得安全的表单,必须检查和验证所有客户端输入。任何不是来自我们系统的信息都是不可信的。
在我们的案例中来自客户的输入:
文件名 姓名 分机 文件内容扩展
我们并不真正关心 minetype,这是用于 Web 服务器的信息。我们关心文件扩展名,因为这是操作系统如何运行/读取/打开文件的指标。我们必须只支持特定的文件扩展名(无论您的管理员的电脑可以处理什么),支持未知文件类型是没有意义的。
名称(不带扩展名)
文件名并不总是有价值的信息。当我处理文件上传时,我通常将其重命名(设置)为 id(用户名、时间戳、哈希等)。如果名称很重要,请始终检查/修剪它,如果您只希望字母或数字删除所有其他字符(我避免留下“/”、“\”、“。”,因为它们可用于注入路径)。
所以现在我们假设生成的文件名是安全的。
内容
当您不支持结构化文件时,您就无法验证文件的内容。因此,让专家程序为您执行此操作...用防病毒软件扫描它们。从控制台调用防病毒软件(小心使用避免注入的机制)。许多防病毒软件也可以扫描 zip 内容(恶意文件,在您的服务器上的文件夹中不是一个好主意)。始终保持扫描程序更新。
在 cmets 上,我建议压缩文件,以避免在管理员机器和服务器上自动执行。然后管理员机器的杀毒软件可以在解压前处理它。
更多提示,不要给客户提供比他需要的更多的信息...不要让客户知道文件保存在哪里,如果没有,不要让网络服务器访问它们进行分发需要。记录奇怪的操作(文件名中的斜线、太大的文件、太长的名称、警告扩展名,如“sh”、“exe”、“bat”),如果发生任何奇怪的事情,请通过电子邮件向管理员报告(很高兴知道是否你的保护工作)。
所有这些都会造成服务器工作负载(更多系统漏洞),因此您可能应该计算在接受新文件上传请求之前扫描/检查的文件数量(这就是我要发起 DDoS 攻击的地方) .
通过快速 google 搜索 Avast! For Linux - Command Line Guide,我不宣传 Avast,我只是将其作为现有示例展示。
最后但同样重要的是,您并不偏执,我管理着一个我编写的自定义翻译系统......垃圾邮件和黑客攻击不止一次发生。
再想一想,在网页上运行的 javascript 仅对客户端计算机是安全的(感谢浏览器的安全性)。我们可以使用它来防止向服务器发送无效帖子,但这并不能确保此类请求不会被执行,因为 JavaScript 可以被绕过/编辑。
所以,所有的 JavaScript 解决方案都只是为了第一次验证(通常只是为了帮助用户纠正错误)和正确设置表单数据。
【讨论】:
以上是关于使 ASP.Net 文件上传安全的主要内容,如果未能解决你的问题,请参考以下文章
将用户上传的 CSV 文件从 ASP.NET 解析到 MySQL DB。安全问题
asp.net core系列 69 Amazon S3 资源文件上传示例