【问题标题】:How to securely store files on a server如何在服务器上安全地存储文件
【发布时间】:2012-05-18 18:56:53
【问题描述】:

我在做什么:

我基本上需要创建一个由用 PHP 编写的登录页面保护的网站,一旦登录,您就会有一个读取整数的搜索栏,并且数据被发送到一个 PHP 脚本,该脚本检索一个以数字为名称的图像.

(我将在此服务器上存储几千张图片以供搜索 - 库存图片)

-

我需要什么帮助:

根据我的研究,我了解到您“不”使用 MySQL 等数据库来存储实际图像,因为速度和效率低下。如果您不将其存储在数据库中,而是按照建议将其保留在服务器的文件系统中,如果有人在地址栏中键入直接 URL,它不会将它们带到我服务器上的文件中吗?

您如何防止这种情况发生。如果没有成功通过登录页面,我不希望服务器上的任何文件都可以查看。

感谢您的帮助,任何见解或建议将不胜感激。这对我来说很重要,因为将来会添加更复杂的信息。

【问题讨论】:

  • 您可以拥有一个无法通过 HTTP 访问的目录,您可以使用 php 脚本检查用户是否已登录,如果是,则从指定目录读取文件并输出。
  • 我已经阅读了将文件保留在“public_html”文件夹之外的内容。这会使它完全无法从http访问吗?那么我的 php 脚本如何访问这些文件呢?
  • public_html 通常是使用 Apache 和 cPanel 时提供文件的目录。这意味着当您键入http://yoursite.com 时,数据将从/var/www/username/public_html 中提取。这也意味着无论您在 URL 中键入什么,/var/www/username不可访问。这也意味着您在此处创建的目录(例如 /var/www/username/files)也将无法访问。在您的 PHP 脚本中,您可以使用 file_get_contents('/var/www/username/files/imagename.extension);` 之类的方式访问它。
  • php 可以访问服务器上的任何文件(取决于权限)它不受网络根目录的限制
  • 好的,谢谢你们,现在我知道如何存储我的文件了。我应该使用数据库来存储文件路径,还是应该完全忽略数据库?对路径进行硬编码,并为输入(图像的名称)提供一个变量保存位置?

标签: php mysql database image


【解决方案1】:

通过 PHP(或任何其他脚本)处理文件下载的推荐方法是使用所谓的“X-Sendfile”响应标头。

PHP 脚本处理身份验证,一旦验证,它将设置一些响应标头和一个“X-Sendfile”,告诉 Web 服务器发送文件;脚本结束,网络服务器接管。

这里有一个简单的例子:

http://www.jasny.net/articles/how-i-php-x-sendfile/

【讨论】:

    【解决方案2】:

    这对于您的情况来说可能有点矫枉过正,但这就是我正在考虑在我正在开发的应用程序上执行此操作的方式:

    首先,有4台服务器,一个web服务器,一个中间件服务器,一个数据服务器

    当有人向 Web 服务器发送请求时,Web 服务器会连接到中间件服务器并请求文件,并传递用户凭据(如会话密钥)和请求的文件。中间件连接到数据库并验证会话和用户对该文件的权限。如果他们有权访问,它将返回错误或二进制数据。如果你在 web 服务器和中间件服务器上都关闭了输出缓冲,你可以从中间件服务器发送 100k 块到 web 服务器,web 服务器将在接收第二块时输出第一个块。

    文件本身可以通过 ftp、sftp 或其他文件共享方式存储在数据库服务器上

    它肯定不如使用 x-sendfile 高效,但是如果有人能够 pwn 您的 Web 服务器,他们仍然无法访问该文件 - 在上述情况下,他们会。 Web 服务器是唯一的公共服务器,因此其余服务器应连接到专用网络。

    您还可以将数据发送到将加密/解密实际文件数据的加密服务器

    如果有人对如何改进这一点有任何想法,我很感兴趣。

    【讨论】:

    • 很有趣,但这肯定比我需要的复杂(但读起来很有趣)。老实说,当时我不知道 .htaccess 并且它可以阻止查看整个文件夹。我已经实现了这一点。我有一个 HTML 登录表单,它获取数据,将其发送到验证用户的处理脚本,如果验证,则将用户发送到搜索页面。用户输入一个 Item # 并被发送到另一个处理脚本,该脚本以数字作为主键访问数据库,保存文件路径和其他信息。如果存在,则拉取文件路径
    • 图像文件夹受 .htaccess ("DENY FROM ALL") 保护。我还使用 SSL 并将有关图像的其他信息存储在 MySQL 数据库中
    【解决方案3】:

    你可以这样做 像这样在php中编写资源服务

    image.php?requestid=.....
    

    在该文件中,您获取 requestid 并从数据库中读取实际链接(本地链接),读取图像文件然后将数据输出到浏览器

    $id = $_GET['requestid'];
    $link = get_local_link_from_id($id);  // return /images/file1.png......
    $data = file_get_contents($link);
    header('Content-Type', 'image/png');
    echo $data;
    

    但我认为你不应该这样做,只是随机重命名文件并创建很多......

    【讨论】:

    • 他们需要保留原始号码,这不是我的系统,而是雇用我的人要求的。这足够安全吗?只要我的 PHP 脚本过滤请求,对吗?
    • GET 从来都不是安全的,即使是 POST 也可能不足以保证安全。
    • @ilis - 你的评论有什么意义? GET 和 POST 是 HTTP 使用的方法,只有在解释用户输入时被误用,它们才是“不安全的”。
    • @N.B.我想我暂时还不足以解释他们不安全的观点。但我会在短时间内返回这里并提供完整的详细信息(几天后)
    • 有什么好讨论的?使用 HTTP 传递数据的唯一方法是使用 GET/POST(在当前上下文中)。你说他们没有安全感。不,他们不是不安全的。不安全的是您如何解释该数据,就像其他任何协议一样。协议或上述两种方法都没有问题。请不要发布误导性的 cmets。
    猜你喜欢
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 2013-03-05
    • 1970-01-01
    • 2011-05-13
    • 2011-06-03
    • 1970-01-01
    相关资源
    最近更新 更多