【问题标题】:Secure way to store files in web server?将文件存储在 Web 服务器中的安全方法?
【发布时间】:2011-06-03 23:38:23
【问题描述】:

我希望我的文件在我的网络服务器中是安全的。只有经过身份验证的用户才能访问这些文件,才能访问这些文件。我曾考虑将数据库中的文件存储为“Long BLOB”,但它最多只支持 2MB 的数据。文件大小可能超过 50MB。还有其他更好的方法来保护文件吗?请帮助我。在此先感谢。

【问题讨论】:

  • 您想以哪种方式访问​​文件? HTTP? FTP?
  • 很确定您可以使用 longblob 在数据库中存储大于 2MB 的文件。理论限制为 4GB。 Max_packet_size 应该是更改限制的正确设置。也就是说,这对您来说不是一个好的解决方案。只是想我会在上面做个笔记。
  • @Sondre:感谢您的关注。
  • @brainless 你觉得我的回答怎么样。我不确定是否适合你,但你永远不知道。

标签: php mysql security file webserver


【解决方案1】:

不要将它们存储在数据库中。将它们放入您的网络目录并使用.htaccess 保护它们。

如果您想通过其他方式进行身份验证,请将文件存储在无法通过网络访问但用户 php 运行时可以读取的目录中。

【讨论】:

  • 提供的链接不再存在。有人可以更新这个答案吗?
  • @marcog 我不认为使用 .htaccess 文件会阻止某人直接访问文件(无论是 PDF、Word doc、PSD 等),对吗?将文件保存在 webroot 之外会阻止直接文件访问,使您的应用程序负责创建指向高价值可下载内容的链接。
  • 您能否举例说明如何使用.htaccess 保护您的文件?
【解决方案2】:

讨论

如果您选择将高价值的可下载内容文件直接保存在 文件系统 上,最好的办法是将它们保存在 webroot 之外。 然后,您的应用程序必须解决为内容(PDF、Word 文档、歌曲等)创建 URL(必要时进行 URL 编码)的问题。

通常,这可以通过使用查询来检索文件路径,然后在用户单击锚点(所有这不会让用户看到真正的服务器端文件路径)。

如果您不希望用户 A 将高价值可下载内容的 URL 共享给用户 B,那么您的应用程序必须以某种方式使链接专门与用户 相关联一个。可以做什么?我应该从哪里开始?

显然,您希望确保用户 A 在会话期间已登录,然后他或她才能下载文件。 不太明显的是如何防止登录用户B使用用户A发送的URL (给用户B)下载A的数字内容。

使用$_SESSION 存储登录用户的ID(数字或字符串)并进行最终查询的那部分(假设内容与用户购买或其他内容相关)将阻止登录用户B 下载他们没有购买的东西,但是您仍然会在处理他们没有购买的物品的 SQL 空集时产生资源损失。这听起来是不错的第二步。

第一步呢?有什么东西可以防止需要先进行查询吗?

好吧,让我们看看。在 HTML 表单中,可以在隐藏字段中使用 XSRF 令牌来验证提交的表单是否确实来自接收 POST/GET 请求的 Web 服务器。一个令牌用于整个表单。

给定一页用户特定的东西要下载(锚点),可以将单个令牌(相同的令牌,但每个页面请求不同)以查询字符串参数的形式嵌入每个锚点的href 属性并存储$_SESSION 中此令牌的副本。

现在,当登录用户 B 尝试使用登录用户 A 的 共享 URL 时,整个事情都失败了,因为用户 A和用户 B 有不同的会话(或根本没有会话),因此有不同的令牌。换句话说,“我的链接和你的一样,但不同。”锚点将与会话相关联,而不仅仅是与页面、用户或内容相关联。

有了这个系统,PHP 可以在不涉及数据库的情况下确定内容请求是否有效(通过将提交的令牌与$_SESSION 中的令牌进行比较)。更重要的是,可以在$_SESSION 中建立时间限制来限制有效 XSRF 令牌的持续时间/生命周期。只需使用time() 函数和基本数学即可。在这种情况下,对于锚点来说,60 分钟可能是理想的令牌寿命。如果单击的锚点的令牌已过期,则让用户再次登录。

总结

如果您使用文件系统上的文件并将路径存储在数据库中,请确保也执行以下操作(至少)。

  1. 对您的内容目录(webroot 之外)应用适当的文件权限。
  2. 对上传的文件使用随机名称。
  3. 在保存上传的文件之前检查重复的文件名。
  4. 只有登录用户才能下载高价值内容。
  5. 拥有一个有效的$_SESSION 系统来阻止会话固定。
  6. 使用散列的 XSRF 令牌使高价值可下载内容的 URL 在每个页面上都是唯一的。
  7. XSRF 令牌在具有终端生命周期时涵盖更多场景。
  8. 根据登录的用户 ID,而不是仅根据产品对用户内容进行 SQL 查询。
  9. 过滤和验证所有用户输入。
  10. 对 SQL 查询使用准备好的语句。

【讨论】:

    【解决方案3】:

    我想到了几个选项。

    如果您使用的是 Apache,您可以使用 htaccess 来密码保护目录。 (第一个谷歌链接:http://www.javascriptkit.com/howto/htaccess3.shtml

    或 将文件存储在 Web 服务器之上。 在 php 中创建一个脚本,允许授权用户访问它们。

    如果您想通过 FTP 进行操作,并且您正在运行 cpanel,您可以创建新的 ftp 帐户。检查 yourdomain.com/cpanel 以确定您是否安装了它。

    【讨论】:

      【解决方案4】:

      在数据库中存储文件是非常糟糕的做法。仅存储有关文件的信息的非常好的做法。名称,扩展名。文件保存在服务器上,如 $id.$ext。这将是一个很好的架构。当用户下载文件时,他会在 DB 中获取带有名称的文件。
      对不起我的英语。

      【讨论】:

        【解决方案5】:

        最好的方法是将文件引用存储在数据库中。文件本身将存储在服务器文件系统中。这样做的复杂性在于确保数据库文件引用和服务器文件系统中的现有文件之间存在引用完整性。某些数据库(例如 sql server 2008)具有维护文件引用对实际文件本身的完整性的功能。

        除了在服务器中保护文件本身之外,还取决于可以将权限配置到文件所在特定文件夹的操作系统。

        【讨论】:

          【解决方案6】:

          如果文件是纯静态的,您可以使用只读或 WORM 媒体来存储数据文件,或者确实从“LiveCD”运行完整的 Web 服务器。它当然不适合每个人的需求,但对于数据完整性至关重要的有限情况,它可以发挥作用。

          【讨论】:

            【解决方案7】:

            可下载的文件可以存储在受 htaccess 保护的文件夹中。如下所示的脚本可用于生成可下载文件的动态链接。

            例如。安全下载链接。 http://codecanyon.net/item/secure-download-links/309295

            【讨论】:

            • 这会阻止直接文件访问吗?
            • @AnthonyRutledge 它阻止直接文件访问,因为没有人有直接文件的 url。您也可以考虑将文件存储在根目录下,然后在安全下行链接中使用相对路径来阻止所有可能性
            • 好的,但是如果我要这样做,我会将我的可下载文件存储在 Web 根目录之外,并且只有在我的应用程序(与数据库一起)提供/构建了链接时才能访问它们.从本质上讲,从来没有直接链接到文件。它们可能看起来像用户的稳定链接,但它们是短暂的。
            • @AnthonyRutledge 安全下载链接确实允许您将文件存储在根目录下
            猜你喜欢
            • 1970-01-01
            • 2013-10-04
            • 1970-01-01
            • 1970-01-01
            • 2018-05-22
            • 2012-05-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多