【问题标题】:Security measures when uploading files via php通过php上传文件时的安全措施
【发布时间】:2011-11-18 23:42:04
【问题描述】:

我有一个可供公众使用的文件上传脚本(例如,不是封闭的工作环境),我担心安全性: 我想允许上传任何文件,每个文件都会上传到它自己的唯一目录,显然,我无法控制是否有人上传恶意文件,但处理这些文件的最佳方法是什么?

我想到了:

完全删除扩展名,并且仅在提供要下载的文件时,将它们的原始扩展名返回(因为所有文件名和位置都将保存在 db 中)

创建一个“安全区”以禁止在目录中运行多个扩展。

禁止上传“不安全”的扩展。

当然,问题是: 有太多“不安全”的文件扩展名来计算它们。 尽管文件包含一些代码,但可以将文件屏蔽为“安全”。 以及许多其他安全风险...

所以...有什么建议吗?

【问题讨论】:

  • 只要您控制文件的位置以及上传后可以访问它们,您就可以控制安全性。该网站的目的是什么?
  • 将文件(甚至是 .exe 或 .sh)加载到服务器,并不承认您有权执行它们。
  • 本站的目的是上传文件分享。

标签: php security file-upload


【解决方案1】:

如果您所做的只是充当文件存储,那么您在乎什么?您没有执行文件或以任何方式查看它们,是吗?

文件扩展名与文件的安全性无关。

编辑:您真正要做的是将文件名与完整路径的校验和一起存储在数据库中。然后您的脚本将通过该校验和,然后将在您的数据库中查找,然后您会以某种方式返回文件。不要使用您的网络服务器来提供文件,否则(正如您在下面的 cmets 中所说)您可能会意外执行上传的 PHP 文件。

【讨论】:

  • 但用户可以访问该文件,该文件将在我的服务器上自行执行。
  • @Itai:不会。我可以复制一个恶意文件,但它不会执行。我可以scp 将它发送到另一台机器,但它不会执行。我可以通过 HTTP 提供它,但它不会执行。
  • 如果,假设用户上传了一些包含 php 脚本的 thisfile.php,他会转到该目录,如果我错了,请纠正我,该文件将被执行。
  • @Itai:哦,是的,这将被执行,但你想这样做:stackoverflow.com/questions/1271899/…
【解决方案2】:

为了适当的安全:

  1. 限制文件大小
  2. 永远不要使用任何用户提供的数据作为文件名的一部分来存储文件。通过数据库跟踪上传并使用其关联记录的主键存储文件
  3. 不要将文件放在可通过 Web 访问的目录中 - 仅允许通过脚本进行访问。然后,此脚本可以在下载标头中填写原始文件名。
  4. 无论您将文件存储在何处,都以非执行权限存储它们。这意味着在 Unix 系统上最多为 0640,在 Windows 系统上最多为 0640。
  5. 限制上传,以防止用户在您的系统中充斥夏季大片的最新蓝光翻录。限制下载以防止您的网站成为下一个软件天堂。
  6. 尽可能多地跟踪有关用户的数据:至少浏览器 ID 及其 IP 地址。更好的是,需要某种形式的身份验证/登录,然后才能让他们靠近网站的文件处理部分。

【讨论】:

  • 你能给#3举个例子吗?
【解决方案3】:

只需将它们上传到您的文档根目录之外,并在请求时使用 php 文件为它们提供服务

【讨论】:

    【解决方案4】:

    为防止服务器端执行,请勿将它们放入可通过网络访问的文件夹中,而是使用脚本来处理发送文件。

    即:

    <?php
    
    // TODO: acl related stuff
    // TODO: Map request to file name
    // Send the file as an attachment
    header('Content-type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . $givenFileName . '"');
    readfile($realFileName);
    

    【讨论】:

      【解决方案5】:

      我认为您可以使用这种方法来确保它的安全

      1- 不要以文件名上传文件(意味着您应该使用md5(rand().time().rand()) ;更改文件名

      )

      2- 在字典中添加空白页面以供上传,您可以添加 .htaccess 以拒绝所有您可以使用的读取

      显示或下载图片的文件

      3- 如果允许使用 -> 您可以在 php 中使用 rename() 将字典重命名为其他名称

      4-检查上传大小,并使用@include();隐藏所有路径

      5- 正如@periklis 所说,如果您可以将文件保存在文档根目录之外,这将有所帮助:)

      6-在你降低文件扩展名后拒绝这个扩展.php , .asp .pl .py .rb .htaccess

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-30
        • 2014-05-13
        • 1970-01-01
        • 1970-01-01
        • 2014-11-19
        • 2018-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多