http_origin 可以被欺骗吗?

Posted

技术标签:

【中文标题】http_origin 可以被欺骗吗?【英文标题】:Can http_origin be spoofed? 【发布时间】:2018-07-27 17:20:50 【问题描述】:

我托管了网站所有者在其网站上运行的 javascript。我的服务器是 LAMP 堆栈。我正在尝试保护已批准网站的脚本。有哪些方法可以做到这一点?我目前正在寻找$_SERVER['HTTP_ORIGIN']Access-Control-Allow-Originallow access。这是最安全的方法吗,可以被欺骗吗?

我的 javascript 是提供服务并且需要安全。想想谷歌分析——人们放在他们网站上的 js。

【问题讨论】:

也许见***.com/questions/4566378/how-secure-is-http-origin 当然可以被欺骗。一切都可以。清理和验证所有输入。脚本标签不使用 CORS,仅 ajax 使用。 【参考方案1】:

您的“安全”模型似乎是基于防止其他人使用您的代码。对此有一些明显的解决方案,但它们取决于您是否破坏了最终用户可能认为安全的内容。

对于未经许可使用您的代码的人,您已经获得了法律保护。而且您描述的方法提供的技术保护有限。

如果你真的认为你的代码非常棒/有价值,那么移动逻辑服务器端并用 JavaScript 编写一个基本的渲染器以通过 websockets 进行连接

【讨论】:

我的javascript是提供服务的,需要安全。想想谷歌分析——人们放在他们网站上的 js。 您发送给客户端的任何内容都不会受到用户操作的保护。您仍然没有对“安全”的含义提供明确的解释:如果您无法解释问题,那么任何人都无法帮助您解决问题。【参考方案2】:

与往常一样,这取决于您要防范什么。

什么会阻止用户使用授权的引用者/来源伪造完整的请求、下载您的 javascript 并将其托管在他们的服务器上?

另外请注意,在某些情况下,referer/origin 可能会被欺骗。例如,某些浏览器扩展(当然如果安装了)一些旧版本的 Java 或 Flash 插件,也许其他东西也允许这种伪造。举个极端的例子,你的内容的恶意消费者可能会要求他的访问者首先安装一个浏览器扩展程序,该扩展程序“允许访问他的内容”,而实际上它允许他伪造引用/来源。

如果您真的想保护您的内容,因为您只想允许授权客户端下载它,不幸的是,实现这一目标的唯一方法是某种身份验证。现在显然您不想验证最终用户,而是发送他的网站,这是一个有趣的场景,超出了这个答案的范围。

除此之外,您可以做的最常见和类似最佳实践的事情可能是您可以为授权网站提供类似于 api 密钥的东西,就像 Google 在其服务中所做的那样。密钥在任何客户页面中都是明文,但如果您有适当的监控,您可以撤销滥用的密钥。请注意,这不是身份验证,任何人都可以从他们的页面源中复制主机网站密钥,但是您将有机会发现滥用行为,例如并非每个人都会安装浏览器扩展程序或插件,并且您会看到给定的引用不匹配api 密钥。在许多情况下,这可能已经足够了。注意,难点不是api关键部分,而是有效监控。

【讨论】:

【参考方案3】:

根据 Web 标准,出于安全原因,不允许通过 XMLHttpRequest (AJAX) 发出的跨域请求以避免一个域访问来自不同域的另一个资源。这适用于通过 XMLHttpRequest 对象发起的请求。引入 origin 标头是为了帮助允许跨域资源共享,同时仍保持对资源的安全检查,并且只会为被视为跨域请求的请求发送。

对于您的情况,检查 Origin 标头将是错误的,因为对托管脚本的请求不是通过 XMLHttpRequest 发起的,而是通过脚本元素的 src 属性发起的。

最佳做法是检查引荐来源标头。这几乎是针对每个请求发送的,并且在实施跨站点请求伪造防御时也可以很好地检查它。

使用正则表达式从发送的引用标头中捕获主机。然后根据您的允许主机列表检查主机

如果捕获的主机未列入白名单,则通过发送您认为合适的 404 或 403 响应来拒绝访问。

$allow = FALSE;
$allowed_hosts = ['http://www.example.com/']; //note the ending slash
$matches = [];
$referrer = array_key_exists('HTTP_REFERER', $_SERVER)? $_SERVER['HTTP_REFERER'] : NULL;
if (!is_null($referrer) && preg_match('/^(http[s]?\:\/\/[^\/]+\/)/', 
$referrer, $matches)) 
    $host = strtolower($matches[1]);
    if (in_array($host, $allowed_hosts)) 
        $allow = TRUE;
    

if ($allow) 
    header("Content-Type: text/javascript");
    header('Cache-Control: max-age=86400');
    echo file_get_contents('path to javascript');

else
   header("HTTP/1 403 Forbidden");
   exit;

【讨论】:

因此脚本在任何关闭了引用的浏览器上都会失败,并且由于引用处理错误而在 Safari 中经常失败。 你能给出一个测试场景来证明 safari 有错误的引用处理。所有主流浏览器都会发送referer 标头,即使在您的本地机器(localhost)上工作时也是如此。为了得到满足,如果引用头不存在,则应中止请求。这就是白名单防御的本质。由于 javascript 不是他所说的公共资源,我相信提供的解决方案会实现它 感谢您的分享。从 IBM 报告中,它说该报告是经过验证的,没有经过测试证明。那是在 2014 年。当遵循网络标准时,一两个产品总是会打破标准。但它会随着时间的推移而修复。所以我看不出为什么我不应该坚持引用标头

以上是关于http_origin 可以被欺骗吗?的主要内容,如果未能解决你的问题,请参考以下文章

HTTP_ORIGIN 的安全性如何?

ARP欺骗如何解决?

我们可以用 php cURL 欺骗 $_SERVER['REMOTE_ADDR'] / 用户 ip 吗?

网络服务器所在的欺骗国家

C语言写ARP欺骗

$_SERVER['HTTP_ORIGIN'] 不起作用