【问题标题】:PHP - How to determine if request is coming from a specific filePHP - 如何确定请求是否来自特定文件
【发布时间】:2023-04-25 21:02:01
【问题描述】:

我在 SERVER_A 上有 fileA.php,在 SERVER_B 上有 fileB.php

fileB.php 向 fileA.php 发出 curl 请求以获取其内容

fileA.php 如何确定请求是专门来自 fileB.php 的?

--

我正在考虑将 fileB.php 中的 $_SERVER['SCRIPT_NAME'] 发送到 fileA.php 但由于有人可以进入 fileB.php 或任何一般文件,只需执行 $_SERVER['SCRIPT_NAME'] = '文件B.php';它并不是那么安全。

那么,出于安全原因,我如何确定请求来自不同服务器上的特定文件?

【问题讨论】:

  • 您是否绝对需要 100% 安全?因为如果是这样,我建议您找到另一种方法。
  • fileA.php 是否需要公开访问?如果您的问题是如何使 fileA.php only 可访问 fileB.php,那么您可以考虑使用 HTTP 身份验证来添加密码保护(然后可以将密码指定为 fileB.php 中 curl 的参数。 php).

标签: php security server-variables


【解决方案1】:

你不能,可靠。您可以尝试设置 HTTP 标头并在另一端进行验证;它不是万无一失的,但它比大多数都好。

【讨论】:

    【解决方案2】:

    不可能,因为你的说法:

    "since someone can go into fileB.php"
    

    【讨论】:

      【解决方案3】:

      为什么不设置一个秘密令牌,并在接收端进行验证?

      // fileB.php
      
      $url = "http://example.com/fileA.php"
           . "?from=fileB"
           . "&token=" . sha1('fileB' . 'myaw3som3_salt!')
      ;
      // then make the cURL request.
      
      
      // fileA.php
      if (sha1($_GET['from'] . 'myaw3som3_salt!') != $_GET['token']) {
          die();
      }
      

      这是一个简单的例子,但你明白了。

      【讨论】:

      • 我使用这种技术将密码存储在数据库中,使用密钥对密码进行 sha1,但如果在这种情况下,“令牌”在 url 中是可见的,这就是我检查的所有内容或我能够查看的所有内容检查他们是否更容易欺骗
      • @John: 也许在散列之前将$_SERVER['HTTP_REFERER'] 包含在字符串中?
      【解决方案4】:

      一旦你在你的服务器之外请求,你就真的无法控制了。如果另一台服务器上的 fileA 可能存在中间人 fileB,您需要重新考虑您的安全模型。具体是什么情况?

      【讨论】:

      • 好吧,如果我不能保护它,我就不会编码。这种特殊情况是我只是想想出一种在客户端服务器上运行代码的方法,而它实际上并不存在并且他们无法看到它。我正在尝试编写类似 fileB.php {eval(file_get_contents(fileA.php));} 和 fileA.php {ftp fileB.php - 如果 fileB.php 的 md5 是原始文件并且请求来自 fileB.php和其他一些事情 - 将 SERVER_A 的 php 代码提供给 eval,否则将其提供给 eval 之类的东西,例如 die()} 只是想看看我可以让 php 做什么 =/
      • 我的意思是 curl,不是 file_get_contents,抱歉。
      • 这听起来确实注定要失败。没有好的方法可以做到这一点。您可以提供一个已被 ioncube 或 zend 编码器“加密”的脚本,并强制它们运行那些 PHP 模块,然后只提供加密的 PHP,但这些已被证明不够安全。
      【解决方案5】:

      一种方法是检查

      $_SERVER['HTTP_REFERER']
      

      PHP 中的变量,但它是由浏览器决定填充它的,因此它不能被完全信任。

      【讨论】:

      • cURL 请求。 Referer 标头将不存在。
      • 您可以使用 cURL 为引用者指定任意值。
      【解决方案6】:

      如果第 3 方有权访问 fileB.php,则几乎无能为力。 REFERER 不给你任何保护。 REMOTE_ADDR 并不容易被欺骗,这可能会让您确信请求是合法的。

      【讨论】:

        【解决方案7】:

        我认为 nickf 是正确的,但只是为了稍微扩展他的答案,这就是我要做的:

        • Server1 上的fileB.php 请求Server2 上的fileC.php
        • Server2 上的fileC.php 返回随机生成的盐,将其存储在带有时间戳的文件或数据库中
        • Server1 上的fileB.php 请求Server2 上的fileA.php,并将预配置的密钥作为其请求主体发送,经过哈希处理,附加随机盐并再次进行哈希处理(例如sha1(sha1('mypassword') .$salt))
        • fileA.php 检查是否在过去 60 秒内生成了盐,如果没有则返回错误
        • fileA.php 使用其最后一个随机盐和预配置密钥 - sha1(sha1('mypassword') . $salt) 再次执行相同的哈希,与 fileB.php 发送的请求正文进行比较。如果它们匹配,fileA.php 将授予对 fileB.php 的访问权限。
        • fileA.php 删除最后生成的盐。

        【讨论】:

        • 另外,如果您担心中间人,请使用 HTTPS...这可能是足够且合理的保护
        最近更新 更多