【问题标题】:Secure .php file, called via JavaScript安全的 .php 文件,通过 JavaScript 调用
【发布时间】:2019-11-07 18:33:33
【问题描述】:

我们的客户使用如下代码使用我们的免费服务:

<script type='text/javascript'>id='example'; width='640'; height='480';</script><script type='text/javascript' src='http://example.com/example.js'></script>

example.js 看起来像这样:

if (typeof (width) == "undefined") {
    var width = '100%';
}
if (typeof (height) == "undefined") {
    var height = '100%';
}
if (typeof (p) == "undefined") {
    var p = '0';
}
if (typeof (c) == "undefined") {
    var c = '0';
}
if (typeof (stretching) == "undefined") {
    var stretching = 'uniform';
}
document.write('<iframe allowfullscreen width="' + width + '" height="' + height + '" scrolling="no" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="true" src="http://example.com/examplefile.php?id=' + id + '&p=' + p + '&c=' + c + '&stretching=' + stretching + '"></iframe>');

问题是人们正在窃取 examplefile.php。我们尝试将 secure_link 与 nginx 一起使用,效果很好,但仅适用于能够在其站点中使用 PHP 代码、生成带有密钥的随机安全令牌的客户端。其他一些客户端只能嵌入 HTML 代码。有没有办法保护 examplefile.php 或者随机更改 examplefile.php 名​​称,并针对我们的服务器进行验证以停止盗取?

也许使用 jQuery?我们需要能够确保 examplefile.php 是由此 JavaScript 代码开始调用的,而不是作为来自外部站点的 iframe 手动添加的。

【问题讨论】:

  • 如果客户端的服务器只有静态内容——没有办法让它真正安全。你甚至可以在 nginx 中使用某种白名单,哪个域可以 iframe 你的页面(Content-Security-Policy),但这很容易破坏。您的一位客户可能会对您不利吗?如果客户只能伤害自己——也许我能找到解决办法。但是,如果客户可能是那个坏人,并且将他的“密码”提供给其他人使用您的服务 - 就没有办法保证它的安全。那么 - 可以给用户“帐户”而不用担心他们将如何使用它?
  • 是的,这是一个选项。看起来我必须实施一个帐户系统,如果我这样做,你有什么想法?
  • 我已经工作了太多小时......对于任何不清楚的句子提前抱歉;)我的想法现在只是想法 - 我什至没有测试它,但我认为它可以工作。我会把它写成答案,因为它太长了,无法评论。
  • 好的,也许在这里。恐怕我的想法是错误的。至少——它有点复杂。但它的第二个核心是$_SERVER['HTTP_REFERER']。只是这太弱了,但如果有其他墙,它就足以保护大多数人了。
  • 我很想看看你的想法。你把它写成答案了吗?谢谢

标签: javascript php jquery html nginx


【解决方案1】:

您可以将 JavaScript 替换为 AJAX 请求,该请求发送带有令牌的自定义 HTTP 请求标头。验证令牌后,您的服务器将响应 URL 以在 iframe 中使用。此解决方案为您提供了控制 URL 的机会,因此您可以将其随机化。

另一种方法是将请求发送到表明您打算访问资源的 URL。它可以使用会话 cookie 进行响应,该会话 cookie 将由后续的 iframe 链接请求携带。

这里有一些普通的 JavaScript 可以帮助您开始使用 AJAX 请求。

var myURL = 'https://www.example.com/path/',
    myCustomKey = 'Custom-Header',
    myCustomValue = 'Custom-Token-Value',
    myRequest = new XMLHttpRequest();

// open request so that custom header can be added
myRequest.open('GET', myURL, true);
// set custom header for request
myRequest.setRequestHeader(myCustomKey, myCustomValue);

myRequest.onload = function () {
    // Request finished. Do processing here.
    if (myRequest.status === 200) {
        // Request was successful
        // use the response
        console.log(myRequest.response);
    }
};

myRequest.send(null);

您必须配置服务器以支持 CORS。见https://enable-cors.org/server.html

【讨论】:

  • 我喜欢这个解决方案,但你认为窃取内容的人能够发送相同的标头并获取文件吗?另外,我不确定如何实现这一点。在我的例子中,你能帮我更多吗?谢谢!!!
  • 没有解决方案是完全安全的。如果您担心重放攻击,请生成一个加密令牌,该令牌对每个域都是唯一的,并且包括引用域和时间戳。然后,服务器端需要验证时间戳是否在预定的时间窗口内,以及引用者是否来自加密域。查看 HMAC-SHA 身份验证,这是 Amazon 限制对 S3 上资源的访问的方式。
【解决方案2】:

如果我理解正确,您希望确保您是唯一使用此资源的人。 一种方法是将example.js替换为生成的JS文件example.php

这个文件有两个职责:

  1. 针对您的服务器验证请求
  2. 输出纯 JS 内容,就好像它是一个 JS 文件(带有适当的标头数据)。

更新

这是我的具体做法:

通过使用 example.php 文件(而不是 example.js),每次用户加载文件时,都会为客户端初始化一个唯一的会话令牌,您将立即在 examplefile.php 中验证该令牌。这样,您可以确保(在某种程度上)请求来自 example.php

【讨论】:

  • 谢谢,但是他们会添加这个 php 文件,我们的情况会和以前一样吗?
猜你喜欢
  • 2015-12-17
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多