在Web服务器中存储文件的安全方式?

2022-08-30 18:15:32

我希望我的文件在我的 Web 服务器中是安全的。只有经过身份验证的用户才能访问这些文件。我想过将文件中的文件存储为“长BLOB”,但它只支持最多2MB的数据。文件大小可能会超过 50MB。有没有其他更好的方法来保护文件?请帮帮我,提前感谢。


答案 1

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

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


答案 2

讨论

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

通常,这可以通过使用查询来检索文件路径来实现,然后在用户单击锚点时使用文件路径将内容(使用等)发送给用户(所有这些都不会使用户看到真正的服务器端文件路径)。header()

如果您不希望用户 A 将高价值可下载内容的 URL 共享给用户 B,则您的应用程序必须以某种方式使链接以独占方式绑定到用户 A。我们能做些什么?我应该从哪里开始?

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

使用来存储已登录用户的 ID(数字或字符串)并进行最终查询的该部分(假设内容与用户购买或其他内容相关联)将阻止登录用户 B 下载他们未购买的内容,但您仍然会产生资源命中,用于处理他们未购买的项目的 SQL 空集。这听起来像是一个很好的第二步。$_SESSION

第一步呢?有什么东西可以阻止从一开始就执行查询的需要吗?

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

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

现在,当登录用户 B 尝试使用登录用户 A 的共享 URL 时,整个操作都会失败,因为用户 A 和用户 B 具有不同的会话(或者根本没有会话),因此令牌也不同。换句话说,“我的链接和你的链接一样,但不同。锚点将绑定到会话,而不仅仅是页面、用户或内容。

有了这个系统,PHP 就可以确定内容请求是否有效,而无需让数据库参与进来(通过将提交的令牌与 中的令牌进行比较)。此外,可以建立时间限制以限制有效 XSRF 令牌的持续时间/生存期。只需使用函数和基本数学。在这种情况下,六十分钟可能是锚点的理想令牌生存期。如果单击的定位点的令牌已过期,请让用户再次登录。$_SESSION$_SESSIONtime()

总结

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

  1. 将适当的文件权限应用于内容目录(在 webroot 外部)。
  2. 对上传的文件使用随机名称。
  3. 在保存上载中的文件之前,请检查是否有重复的文件名。
  4. 只有登录用户才能下载高价值内容。
  5. 有一个有效的系统,阻止会话固定。$_SESSION
  6. 通过使用散列 XSRF 令牌,使高价值可下载内容的 URL 在每个页面上唯一。
  7. XSRF令牌在具有最终生存期时涵盖了更多场景。
  8. 根据登录用户的 ID(而不是产品独占)对用户内容进行 SQL 查询。
  9. 筛选并验证所有用户输入。
  10. 将预准备语句与 SQL 查询结合使用。

推荐