上传图片 - 安全

时间:2011-02-12 15:46:57

标签: asp.net-mvc security file-upload asp.net-mvc-3

设定:

我正在为电子教学套件编写管理实用程序。使用此实用程序,教师可以编写课程,添加/上传图像等。

我的问题是关于上传文件时的安全漏洞,特别是图像文件。

以下代码是我上传新图像文件的POST的控制器代码:

[HttpPost]
        public virtual ActionResult StepImage(int CourseId, int StepOrder, HttpPostedFileBase file)
        {
            service.CourseId = CourseId;
            service.StepOrder = StepOrder;
            if (file.ContentLength > 0)
            {
                var fileName = Path.GetFileName(file.FileName);
                var fileExtension = Path.GetExtension(fileName);
                if ((fileExtension == ".jpg") || (fileExtension == ".gif") || (fileExtension == ".png"))
                {
                    service.StoreImageFileName(fileName);
                    var path = Server.MapPath("~/[path to where images are uploaded]/" + service.CourseId + "/");
                    if(!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    file.SaveAs(path + fileName);
                }
                else
                {
                    // Refactor notice : Validation for invalid file extension
                }
            }
            else
            {
                // Refactor notice : Validation for no file chosen
            }

            return RedirectToAction(MVC.Admin.StepEditor.Actions.Edit(CourseId, StepOrder));
        }

您可以从上面的代码中看到我检查文件扩展名并且仅允许.jpg,.gif和.png。

问题

  1. 我尝试将文件存储在App_Data文件夹下,但当视图尝试显示图像时,这会导致403禁止响应。

  2. 所以我把它们放在〜/ Images /...

  3. 这有安全隐患吗?有人可以上传带有.jpg扩展名的.exe文件并让它执行baddie代码吗?

    必须说风险很低,因为只有导师才有权使用上传文件的页面,但你只需要一个不满的导师...或者他们将登录详细信息提供给学生。或者其他什么。

    1. 该代码中的任何其他安全风险?
    2. PS:

      基础知识来自Scott Hanselman和Phil Haack关于使用ASP.NET MVC 2 +上传文件主题的博文:

      Phil Haack post

      Scott Hanselman post

1 个答案:

答案 0 :(得分:6)

将图像放在App_Data文件夹中时会收到403响应,因为IIS会阻止任何浏览器直接访问App_Data中的文件。

将它们放在〜/ Images /中,但根据该文件夹的安全性,这可能意味着任何人都可以列出〜/ Images /和/或查看图像的内容。默认情况下,IIS禁止列出任何文件夹的内容,但允许任何人查看图像。因此,如果有人知道图像的文件名,他们就可以查看它们。

解决方案是使用URL based authentication。只有导师(或任何需要的人)才能看到图像。

如果您想完全控制谁在哪些页面上看到了什么,您仍然可以将图像放在App_Data文件夹中,然后将它们流式传输给谁或任何需要它们的人like this

关于将.exe作为jpg上传,这当然是可行的。它甚至适用于任何类型的文件。

但是,您将文件保存到磁盘,不要自己做任何事情。这使得.exe-as-jpg在您的服务器上执行的风险非常小。除非有人在.net代码中发现了强制.net执行jpg的漏洞,否则这是不太可能的。

您还可以在视图中向用户显示jpg。这又带来了安全风险,可能是用户的浏览器有一个漏洞,迫使它在用户的计算机上执行.exe-as-jpg。但是,我认为这种情况仍然不太可能发生(但并非不可能。已经在see this之前完成了。)

为了防止这种情况,您需要在服务器端检查每个图像以查看它是否真的是图像。然而,这些(可能不存在的)安全风险非常小,即使利用这种风险也需要知道很多计算机和编程的人。就个人而言,我不担心这个。

绝对安全是不可能的(好吧,没有打开计算机。如果它什么都不做,毕竟什么都不会出错)。这一切都取决于你想要多少安全性以及多少时间和安全性。你可以投资的钱。