http_origin可以被欺骗吗?

时间:2018-02-16 18:30:52

标签: javascript php security

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

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

3 个答案:

答案 0 :(得分:0)

根据Web标准,由于安全原因,不允许通过XMLHttpRequest(AJAX)发出的跨域请求避免一个域从另一个域访问另一个域。这适用于通过XMLHttpRequest对象发起的请求。原始标头用于帮助允许跨域资源共享,同时仍然保持对资源的安全检查,并且仅针对被视为跨域请求的请求发送。

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

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

使用regex从发送的referer标头中捕获主机。然后根据允许的主机列表检查主机

如果捕获的主机未列入白名单,则拒绝访问,方法是在您认为合适时发送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;
}

答案 1 :(得分:0)

与往常一样,这取决于您想要保护的内容。

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

另请注意,在某些情况下,referer / origin可能会被欺骗。例如某些浏览器扩展(如果安装的话)某些旧版本的Java或Flash插件,也许其他东西也允许这样的伪造。作为一个极端的例子,您内容的胭脂消费者可能会要求他的访问者首先安装一个浏览器扩展程序,以便访问他的内容",而实际上它允许他伪造引用者/来源。

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

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

答案 2 :(得分:0)

你的模特"安全"似乎是基于阻止其他人使用您的代码。有一些明显的解决方案,但它们取决于你打破最终用户可能认为是安全的。

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

如果您真的认为您的代码非常精彩/有价值,那么请移动逻辑服务器端并在JavaScript中编写基本渲染器以通过websockets进行连接