【问题标题】:Where is better to store uploaded files in DB as BLOB or in folder with restrictions?将上传的文件作为 BLOB 存储在 DB 中或有限制的文件夹中哪个更好?
【发布时间】:2013-05-03 02:07:08
【问题描述】:

我在我的项目中使用FileUpload。而且这个项目的访问量会很高(这不是我的野心,只是因为 Web 应用程序确实与支付系统一起工作,这就是为什么它会处于高负载状态)。我想知道,存储用户文件有什么更好的方法?我的项目基于 ASP.NET

我建议两种变体:

  • BLOB 对象另存为/加载到数据库中/从数据库中加载
  • 保存/加载到/从文件夹文件将在该文件夹中找到并保存有关表中文件的信息以供所有者识别,BNF中的表设计:李>

<user_files> ::= ( <id ::= int, primary_key, auto_increment, indexed><user_id ::= int><file_guid ::= varchar(255)>) | nil

我更喜欢 BLOB ,但害怕未来的高负载。因为,从数据库中获取数据需要更多的 CPU 时间和内存分配,因为:

  • 我需要使用一个连接器,它将打开一个新的套接字来连接到 DB localhost
  • 然后必须调用存储过程来获取 BLOB 对象
  • 在客户端,我必须从连接器的某些类中获取结果
  • 我必须反序列化它
  • 然后只是将文件以未压缩和未损坏状态发送给用户,以便用户稍后可以在某些编辑器中打开它(文件通常是图像和 ms-office 文档)

由于我认为所有这些操作可能会减少服务器工作并且需要更多时间,我认为对于 2000 个在线用户来说会很慢,这将非常快速地交换文档

至于文件系统上的存储文件,我看到的唯一问题是:

  • 正确保护文件的访问权限,因为不同的用户不得查看其他文档,并且必须为其他用户隐藏。恐怕,因为 IIS 的 Windows 系统用户(IISUser ...)可以看到用户上传文件的文件夹,否则用户将无法上传任何内容,因此该文件夹将是公共的.我只看到了制作 Windows 服务并将 IIS 文件夹用作临时上传的解决方案。 Windows 服务将从它获取文件并放置到安全文件夹中,网络用户将无法在该文件夹中看到它。

但是,也许,我的想法有问题,这就是为什么我要问你一个建议,因为我想让系统更完美。

谢谢!

【问题讨论】:

    标签: asp.net security database-design file-upload blob


    【解决方案1】:

    正确保护文件的访问权限

    如果您遇到这种情况,您已经违反了 OWASP 安全准则,因为您的文件是 insecure direct object references。这意味着用户可以直接访问文件,因为您在 IIS 上打开了一个完整的子文件夹(如 www.mysite.com/files/some_file.pdf)并且您的文件可能有一个名称。

    你应该做的是:

    1. 在数据库中注册一个具有唯一性的文件;不是它的数据,只是它的名称和上传它的用户(可选地包括权限或角色)。
    2. 将文件存储在磁盘上,其中文件名是数据库标识符。
    3. 不允许直接访问,而是编写一个特殊的 HttpHandler 来接收文档的 id(就像在数据库中存储文件时所做的那样)。

    采用这种方法时,您可以实现以下目标:

    1. 文件具有唯一编号,可防止它们在磁盘上发生命名冲突。
    2. HttpHandler 可以检查下载该文件的用户的数据库是否具有这样做的适当权限。
    3. 由于使用了 ID,因此您不容易受到规范表示攻击,攻击者会发出如下请求:www.mysite.com/file.ashx?file=..\web.config

    所以从安全角度来看,将文件存储在磁盘而不是数据库上是没有问题的。

    【讨论】:

    • 感谢 Steven 的建议,但问题是,如果我不启用这样的文件夹访问规则(对于 IIS 用户,和你写的类似):cs419427.vk.me/v419427458/62de/x_tCHnEWSfs.jpg,关于“不允许直接访问”,所以临时文件夹必须存在,并且必须有将数据写入文件夹的规则,否则不会有任何文件上传,那么最好做什么?制作一个 Windws 服务并使用 IIS 文件夹作为临时上传?
    • 关于第三个选项,我在私有区域中的 url 是用 GET-params 和 cookies 编码的(有使用 AES 和 base64 修改算法,还有 url-rewrite using ),所以很难简单地插入易受 URL 正文影响的 smth
    • 您的网站写入文件的文件夹应位于 IIS 文件夹之外,并且 IIS 用于运行您的网站的用户应配置为对该文件夹具有读/写访问权限。
    • 这对我来说很奇怪,因为 ASP.NET 网站无法保存到具有文件系统操作系统的任何文件夹中,因为所有文件都使用 ASP.NET 中的 FileUpload 表单传输在 CodeBehind 中像这样:System.IO.Path.Combine(Server.MapPath("uploads") 并且您不能在不使用服务器命名空间的情况下保存文件,否则您将尝试保存不在服务器文件夹中时出现异常,因此在任何情况下它都会保存到 IIS 的文件夹中,因为 ASP.NET 项目托管在 IIS 上,它看不到比 IIS 更低级别的文件夹。
    • 您始终可以将文件存储到网站外的任何目录,但您可以使用FileUpload.SaveAs方法写入任何路径,例如:fileUpload.SaveAs("c:\\file.txt")。例如看这个例子:msdn.microsoft.com/en-us/library/…
    【解决方案2】:

    随着时间的推移,存储在数据库中的扩展性会更好。如果您使用文件夹解决方案,并且有一天您需要或决定使用集群,那么在整个服务器场中同步文件将会非常糟糕。

    尽管从数据库中获取内容可能更占用 CPU 资源,但它确实简化了很多事情(您的代码肯定会更易于维护和移植),而且您始终可以指望托管和处理成本会随着时间的推移而减少。

    您还可以缓存内容以提高速度。无论哪种方式,我希望这些文件在上传后不会发生太大变化。

    【讨论】:

      猜你喜欢
      • 2020-03-09
      • 1970-01-01
      • 2015-05-08
      • 2023-03-25
      • 2021-04-30
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多