【问题标题】:PHP get the site that calls your script via file_get_contentsPHP 通过 file_get_contents 获取调用您的脚本的站点
【发布时间】:2011-11-16 07:54:21
【问题描述】:

我的网站上托管了一个 PHP 脚本,它根据传递的 GET 参数输出一个值。

其他网站通过 PHP 函数 file_get_contents 从他们自己的 PHP 脚本中调用此脚本,并使用 url 和获取参数,并仅返回请求的值。

我正在尝试仅允许某些域访问此脚本,并且一直在使用 HTTP_REFERER 检查谁在调用该脚本。

if (isset($_SERVER['HTTP_REFERER'])) // check if referrer is set
{
    echo $_SERVER['HTTP_REFERER']; // echo referrer
}
else
{
    echo 'No referrer set'; // echo failure message
}

当我使用 file_get_contents 时,我没有设置引荐来源网址,但如果我使用从页面到具有上述代码的脚本的点击链接,引荐来源网址会正确显示。

我是否使用了错误的函数 (file_get_contents) 来调用外部脚本,有人可以建议正确的函数还是应该这样做?

非常感谢任何帮助。 谢谢

【问题讨论】:

  • 请记住,HTTP“Referer”标头是一个可选标头——站点无需将其发送给您,而且很容易被伪造。如果您真的只希望某些人使用您的资源,最好使用某种形式的身份验证。
  • file_get_contents 默认是一个完全独立/全新的请求。不会有引用者,因为没有页面引用该连接。如果您希望它发送引用标头,则必须设置流上下文:php.net/manual/en/function.stream-context-create.php

标签: php file-get-contents referrer


【解决方案1】:

您不能使用 HTTP_REFERER 执行此操作。

它由客户端设置的HTTP_REFERER,它可以是客户端想要的任何东西。

您必须改用密码/密钥身份验证机制。

【讨论】:

  • 非常感谢,明白了。该密钥是否不会嵌入到他们服务器上的任何脚本中,然后可能会被未来的开发人员欺骗?只是一个想法。
  • 显然密钥必须保密
  • 那么密钥不会位于调用网站脚本中并且不会保密吗?调用站点必须知道密钥,我的观点是阻止他们将密钥传递给其他站点?否则在这种情况下如何保持这种保密性。只是好奇而已。干杯。
  • 您应该为每个允许的用户提供不同的密钥,而不是将其嵌入到您分发的脚本中
【解决方案2】:

请记住,HTTP 标头“Referer”是可选标头 - 无需网站将其发送给您,而且很容易被伪造。如果您真的只希望某些人使用您的资源,最好使用某种形式的身份验证。

通常Referer:由网络浏览器发送,但没有必要这样做——例如,如果referer 是安全站点,他们就不会发送它。使用 PHP file_get_contents() 在技术上无论如何都没有推荐人;您不会被任何地方“推荐”。

请考虑:

  • 按 IP 地址锁定(但请记住,多个域可以共享一个 IP,并且域的 IP 可以更改。)
  • 使用某种形式的身份验证(最好不是以纯文本形式传输密码的!)

在决定应用正确的安全性时,您应该考虑您需要该服务的安全性,以及可能会受到哪些威胁。

【讨论】:

  • 非常感谢,明白了。
【解决方案3】:

你会更好地基于 IP 地址而不是域进行限制,更可靠。只需保留一组允许的 IP 并调用 in_array($_SERVER['REMOTE_ADDR'],$allowedAddresses) 进行验证。

或者只需要通过 cookie 或 HTTP auth 进行身份验证...

【讨论】:

  • 同意。推荐人永远不应该用于安全。它不可靠,易于操作,并且经常被浏览器完全禁用。
  • 只要您可以允许该 IP 上的任何人进行连接,并且假设您的 IP 不会改变,这就可以正常工作。共享主机服务可能允许从一个 IP 地址连接一百个不同的“域”,此外,如果您的真实客户移动主机,您将不得不更新 IP。因此,如果您选择通过 IP 锁定,请考虑这些问题。
  • @Matt 我知道 - 我想您可以使用反向 DNS 查找 (gethostbyaddr()) 来扩展它,但这会减慢脚本执行速度,需要正确配置 rDNS 并且仍然无法解决共享托管问题。但是,如果您按域进行限制,那么无论您如何进行欺骗都非常容易进行欺骗,以至于不值得费心。我认为要求某种身份验证是唯一实用的方法,但我想我还是会提到 IP 方法。
  • 谢谢,我现在正在使用这个解决方案。 - 编辑所有这些都是我写的,是的,动态IP肯定是个泡菜。已经研究了将 ip 解析为域,并且似乎很多服务器都是通用主机。我会密切关注他们的IP,看看它们是否是静态的。然而,很可能没有足够的脚本用户来担心不明确的主机。谢谢大家。
【解决方案4】:

可能想要使用流上下文中的某些东西来设置额外的标头。

http://us.php.net/manual/en/function.stream-context-create.php

此外,如果需要,您可以设置一个“秘密”标头来验证请求,而不是引用者。

【讨论】:

  • 代理倾向于剥离他们无法识别的标头,这会破坏秘密标头的想法 - 不过想法不错...
  • 如果有代理,可以在请求中使用 cookie 标头,或者使用其他十几种不同的标准身份验证方法中的一种。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 2023-03-27
  • 2016-03-22
  • 2010-12-06
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多