【问题标题】:How to restrict/validate file upload filetypes server side on IIS如何在 IIS 上限制/验证文件上传文件类型服务器端
【发布时间】:2012-08-07 23:39:29
【问题描述】:

我想要一个用户有权上传到我的 IIS 服务器的文件类型白名单(我使用 IIS v7.5)。

我有什么选择?例如,为了在我的控制器中将特定操作的文件大小限制为 5MB,我将此部分添加到我的 webconfig:

<location path="home/fileupload">
  <system.web>
    <!-- maxRequestLength is in kilobytes (KB) -->
    <httpRuntime maxRequestLength="5120" /> <!-- 5MB -->
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- maxAllowedContentLength is in bytes -->
        <requestLimits maxAllowedContentLength="5242880"/> <!-- 5MB -->
      </requestFiltering>
    </security>
  </system.webServer>
</location>

webconfig 中是否有设置允许文件类型白名单的选项?还是唯一的选择是在文件完全上传时验证代码中的文件类型?推荐的技术是什么?我如何确定 .docx、.pdf、.jpg 等文件确实是它们的样子?

【问题讨论】:

  • 是否有理由不在客户端验证它?
  • 因为不是所有的浏览器都支持这个功能,也因为一切都应该在服务器端进行验证!
  • @AlexandreJobin 您有多确定该文件是用户所说的内容?
  • @Jared 因为用户上传的文件将被其他人使用。可以肯定的是,对于我的需要,我的要求有点矫枉过正。但是因为我必须制作一个模块来管理上传,所以我对自己说,我会花时间在第一时间把它做好,这个模块对我们所有的项目都有好处。如果 .exe 文件被重命名为 .docx 或 .zip 文件并且有人试图打开它会怎样?会不会很危险?我不知道,我试图确保一切安全:)

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


【解决方案1】:

由于您想要服务器端,您可以使用文件 mime 类型。

THIS 帖子展示了如何根据文件内容(而不是通过扩展名)确定 MIME 类型。

如果您确实想将输入限制为特定文件扩展名,您可以简单地检查输入名称与您想要接受的名称。如果通过了,您可以对我链接的帖子中的库进行外部参照,以确保用户不只是更改您的文件扩展名。

这样做可以很好地确定文件是您想要接受的文件!

编辑:目前基于 cmets.... 根据您所说的,您正在寻找这种方法应该非常适合您。如果您只是想将其限制为其中一个 cmets 中列出的文件类型,我的建议是……对文件扩展名进行简单检查。如果这是有效的,则将文件传递给链接中列出的urlmon.dll。确保它不会作为无效类型返回....aka Executable/java/zip/etc。如果它不是无效类型,那么您将非常确定它是一个安全文件!

最后,通读该帖子上的 cmets 看起来 urlmon.dll 可能隐式支持您想要的所有文件类型,这将消除检查它是否不是可执行文件或类似性质的东西的需要,但是您需要确认 doc/docx/xsl/xslx 确实返回了有效的 mime 类型。

【讨论】:

    【解决方案2】:

    不,没有 web.config 设置来限制上传的内容。 验证上传数据的唯一可能方法是在代码中实际验证该数据。

    即使有设置,也无济于事,因为它将基于从客户端接收到的 Content-Type 标头,这可能是完全错误的。

    在代码中,您当然可以查看 Content-Type 标头,但如果您尝试验证上传的数据是否属于特定类型,则必须根据类型手动执行此操作您期望的数据。对于图像,这很容易。对于其他文件类型,这可能要困难得多。

    【讨论】:

    • 那么您验证文件的技术是什么?你知道一个可以验证文件真实类型的好库吗?
    • 这取决于文件。没有神奇的解决方案可以验证所有类型的文件。您要使用哪种文件?
    • 对于我的实际项目,我需要验证 pdf、doc、docx、xls、xlsx、图像。我不会有任何视频或音频。仅可打印的文档。
    • 可以通过尝试将其解析为给定的文件类型然后处理异常来验证任何文件类型。图像可以通过前几个字节来验证,这里已经有答案了。以下是一些示例:stackoverflow.com/questions/210650/…
    • 这不是唯一的方法...但是其中一种方法非常复杂,我刚写了一个,我打算很快写博客...但基本上你必须用 C++ 编写一个 Native Module并订阅 OnAcquireRequestState(本机,而不是 .Net)。然后检查 HttpMethod 是否为帖子。然后使用 HttpRequest::ReadEntityBody 将 post 数据逐块加载到一个完整的块缓冲区中。块计数在 HttpRawRequest... 然后使用 Mime 类型解析器来解析文件名的发布数据。如果那里有坏文件,请返回 Request Finished 并设置错误响应......还有很多。
    【解决方案3】:

    Data Annotations 是您正在寻找的,这里有一个搜索可能对您有所帮助,google data anotaions

    更新

    我认为它验证了文件扩展名。如果您不想依赖file extensions,我认为您最好的选择是验证MIME types。这更复杂,并且因浏览器而异,并且可以伪造(尽管这比伪造扩展更复杂。)

    一个简单但不是免费的选择是使用Telerik RadAsyncUpload

    您可以自己编写此代码(尽管我从来没有搞砸过)this 可能会让您入门。 (这篇文章讨论了没有 IIS 就无法可靠地检测 mime 类型的事实,但它应该能让您顺利上路。)

    希望这能让你继续前进。如您所知,您可以通过文件大小来限制文件,通过扩展名进行验证,如果您通过 MIME 类型添加验证,我认为您已经尽了最大努力。我认为这是您可以做的所有事情,以确保安全并且不排除有效文件;虽然我听说过散列文件和其他一些选项;但这些将最挑衅地排除合法文件。

    另外,正如我所提到的,MIME 类型可能是伪造的并发送到您的服务器,为了更加安全,您应该在客户端和服务器端进行验证。

    【讨论】:

    • 数据注解会检查文件的有效性还是只检查文件扩展名?
    • RadAsyncUpload 将过滤文件扩展名,所以这也是我自己在服务器端和客户端也可以轻松完成的事情。我使用的是他们控件的 MVC 版本:)
    • @AlexandreJobin 我相信也可以过滤 MIME 类型。但是我认为它的价格更高。
    猜你喜欢
    • 2011-11-11
    • 2021-10-14
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2012-03-19
    • 1970-01-01
    相关资源
    最近更新 更多