【问题标题】:How to check if a request if coming from the same server or different server?如何检查请求是来自同一服务器还是来自不同服务器?
【发布时间】:2011-03-23 19:01:17
【问题描述】:

如何检查正在接收的请求是否来自同一服务器??

假设,我的域名位于 www.domain.com。现在我有 php 处理文件,它将处理通过该域托管的表单。仅当请求是从域内发送时才会执行此过程,即。 www.domain.com 以及从其他域发送的任何其他请求都将被丢弃。

【问题讨论】:

  • 你的意思是检查请求php文件的域的url
  • 我将发表评论,因为我不确定,但您不能只获取请求者的 IP 并查看它是否与您的服务器的 IP 匹配吗?我在我的一个 asp.net 应用程序中做了类似的事情
  • 使用 curl 我可以将 REFERER 设置为“www.domain.com”,并从我的服务器(在 www.mrhacker.com)调用表单 url(在 www.domain.com),但是 $_SERVER['HTTP_REFERER'] 将给出 www.domain.com 的值(几乎)来自客户端的任何东西都可以被欺骗!我说的差不多,因为普通乔不能欺骗IP地址,你只能通过代理发送。

标签: php


【解决方案1】:

基本上:你不能。
使用 HTTP 协议,每个请求都独立于其他请求。


第一个想法是检查 Referer HTTP 标头,但请注意:

  • 可以伪造(由浏览器发送)
  • 它并不总是存在。

所以:不是一个可靠的解决方案。


一个可能的,并且比Referer想法更好的解决方案可能是使用nonce

  • 显示表单时,在其中放置一个隐藏的输入字段,包含一个随机值
  • 同时,将该随机值存储到与用户对应的会话中。
  • 提交表单后,检查隐藏字段的值是否与会话中存储的值相同。

如果这两个值不相同,则拒绝使用提交的数据。

注意:这个想法经常被用来帮助对抗CSRF——并集成在一些框架的“表单”组件中(例如Zend Framework

【讨论】:

  • 这是对这个问题的完整而准确的答案。
  • 但是当您在不同的标签页中打开同一个网页时,这是一个问题。因为随机值在每个选项卡中都会再次生成,所以用户必须坚持使用他当前的选项卡。
  • 在制作 API 时如何做到这一点?
  • @Jordy 我正在考虑存储像这个会话数组这样的令牌 $_SESSION['usertokens'][] = rand();然后当用户提交表单时,我们可以使用带有 $_SESSION['usertokens'] 的 inarray() php 函数来检查它。这是一个更好的逻辑吗?
  • @VishalParkash 您可以通过在通过 api 提交值时发送唯一密钥来使用 http_authorization 标头变量。
【解决方案2】:

这将检查是否有引用者,然后将其与当前域进行比较,如果不同则来自外部引用者

if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
}
}

【讨论】:

  • 很好的解决方案,但它不适用于端口号,例如在 localhost 上托管测试服务器时。
  • 这是可以伪造的。它缺乏对 TCP/IP 工作的深入了解。
【解决方案3】:

我知道这是一个旧线程,但其他人可能会发现它相关。

答案是:可以。但这取决于您的 Apache/nginx 服务器是否设置为使用所需信息填充 $_SERVER 变量。大多数服务器都是,所以可能你可以使用这种方法。

您需要做的是从 $_SERVER 变量中提取 HTTP_REFERER 并与您的域进行比较。

<?php
function requestedByTheSameDomain() {
    $myDomain       = $_SERVER['SCRIPT_URI'];
    $requestsSource = $_SERVER['HTTP_REFERER'];

    return parse_url($myDomain, PHP_URL_HOST) === parse_url($requestsSource, PHP_URL_HOST);
}

【讨论】:

  • 这是可以伪造的。它缺乏对 TCP/IP 工作的深入了解。
猜你喜欢
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多