【问题标题】:Javascript location.hostname Safe?Javascript location.hostname 安全吗?
【发布时间】:2011-08-20 14:57:16
【问题描述】:

假设我有一个 php 生成的 javasrcipt 文件,其中包含当前登录的用户名、id 号和电子邮件地址。简单的 document.location.href 查找会阻止远程站点确定当前登录的用户吗?

这样安全吗?

if(window.document.location.hostname == 'domain.com')
var user = {
          name:'me',
          id:234243,
          email:'email@email.com'
};
else alert('Sorry you may not request this info cross sites.');

一开始我觉得它是安全的。

编辑:我最初认为这很明显,但我正在使用 cookie 来确定当前登录的用户。我只是想防止跨域访问用户信息。例如,如果删除了 if 语句,恶意站点 A 可以嵌入 javascript 文件并访问用户信息。通过添加 if 语句,用户 js 对象永远不会出现。不支持跨站点 ajax,因此只有通过 javascript 插入,恶意站点才能尝试确定当前登录的用户。

编辑 2: 使用 php 检查我的 http_refer 是否安全?如果还为客户端启用了缓存怎么办?例如,如果用户访问我的站点 A 下载了用户脚本,然后访问站点 B 恶意站点,那么脚本会被缓存,从而绕过服务器检查用户的 http_refer 的需要?

【问题讨论】:

  • 为什么需要将用户信息放入javascript? php 是服务器端的并且已经安全。无论如何,您可能想使用 https :)
  • 我正在设置一个实时 ajax 应用程序,它在那里是为了方便。
  • 那么您只需要在 ajax 加载的页面上再次生成、重新获取 user_info 即可。现在我知道你将使用 ajax 来传递用户变量,那么它是不安全的。
  • 不清楚您要防止的攻击是什么。如果这是 CSRF,那么答案是:NO.
  • @Rock 那你建议如何修复它?

标签: javascript security


【解决方案1】:

你基本上是在说“这是银行金库的钥匙,这是警卫的日程安排,这是工作人员的日程安排。但是,如果你不是 Acme Security Company 的人,就假装我没把这个给你”。

“哦,当然,没问题,让我假装撕碎这张纸条,然后租一辆大卡车把你的保险库里的东西拖走”

【讨论】:

    【解决方案2】:

    你真的不想尝试这样的事情。假设我在经营一个邪恶的网站;我该怎么办?

    <script>
    RegExp.prototype.test = function() { return true; };
    </script>
    <script src="http://yoursite.example.com/dynamicjs.php"></script>
    <script>
    alert("Look at the data I stole: " + user);
    </script>
    

    【讨论】:

    • 您如何建议链接到脚本?有什么办法可以防止这种情况发生吗?
    • 我已将条件更改为window.document.location.hostname == 'domain.com',我正在考虑检查http_referrer。
    • 检查引荐来源服务器端是安全的。我会怀疑 JS 中的任何东西,尽管我想不出有什么东西会破坏你的检查。
    • 缓存会允许恶意网站绕过引荐来源网址检查吗?例如,用户访问我的网站缓存包含用户信息的脚本。然后用户访问一个恶意站点,该站点查询已经在用户缓存中的脚本,因此不会有响应发送到我的服务器检查 http_referrer。我是否必须为包含用户信息的脚本禁用缓存,还是有其他解决方案?
    • 我不这么认为...但实际上,最可靠的就是不在 .js 文件中包含敏感信息。如果您使用的是 php,您应该能够只在服务器端将脚本包含到您的主页中。
    【解决方案3】:

    不,您所拥有的内容并不“安全”,因为它会将这些详细信息透露给 任何人 请求包含该 JavaScript 的 HTML 页面。他们所要做的就是查看服务器返回的文本(包括脚本)。

    归根结底是:要么您已对另一端进行了满意的身份验证,在这种情况下您不需要在 JavaScript 中进行检查,或者您没有,在这种情况下您不想要将详细信息输出到响应全部。客户端 if 声明没有任何目的。试试这个:http://jsbin.com/aboze5 它会说你不能请求数据;然后做一个查看源代码,注意可以看到数据。

    相反,您需要检查请求的来源服务器端,如果请求的来源未经过身份验证,则根本不要在脚本中输出这些详细信息。

    更新 1: 你说的如下:

    我专门试图确定 document.location.href 是否可以被伪造。

    是的,document.location 可以通过隐藏 document 符号来伪造(尽管如果你足够努力的话,你可能会发现):

    (function() {
        var document; // Shadow the symbol
    
        document = {
          location: {
            href: "http://example.com/foo.html"
          }
        };
    
        alert("document.location.href = " + document.location.href);
    })();
    

    Live copy

    跨域检查必须在浏览器内部进行,JavaScript 代码级别的任何事情都无法安全可靠地进行。

    但这真的没关系。即使不能伪造,引用的示例代码也不能保护数据。在客户端检查完成时,数据已经发送到客户端。

    更新 2:您添加了一条关于检查 HTTP_REFERER(原文如此)标题的注释(是的,它确实拼写错误)。可悲的是,不,你不能相信这一点。 HTTP_REFERER 可以被欺骗,单独可以被抑制。


    题外话:您可能已经这样做了,但是:在传输个人详细信息时,您已承诺保密(我不知道您是否有,但希望如此),使用 HTTPS(例如 SSL)。但重要的是要记住,虽然 HTTPS 确保无法在传输过程中读取数据,但它无法确保请求的来源经过身份验证。例如,您知道对话是安全的(在合理和当前实践范围内),但您不一定知道与谁交谈。这就是身份验证的用武之地。

    【讨论】:

    • 但是您是否不需要访问客户端计算机,从而提供过多的潜在安全威胁?我认为 javascript 阻止了跨站点 ajax。
    • @Lime:如果有人直接请求该 URL?从浏览器或爬虫/蜘蛛?或通过curl,或wget?您的代码实际上只是根据位置从对象文字初始化 user 对象。但是无论您是否使用它来初始化user,任何人都可以查看对象文字。
    • 我设置了一个 php auth 系统。它使用 cookie 来验证用户是否已登录。如果有人使用 wget 请求脚本,我将使用空白页或空的 user js 对象进行响应。具体来说,我正在使用 Kohana。我只是想阻止对当前登录用户信息的跨域访问。
    • @Lime:归根结底是:要么您已经对另一端进行了满意的身份验证,在这种情况下,您不需要在 JavaScript 中进行检查,或者您不需要,在这种情况下,您根本不想将详细信息输出到响应中。客户端 if 声明根本没有任何目的。试试这个:jsbin.com/aboze5 它会说你不能请求数据;然后做一个查看源代码。
    • 我特别想确定 document.location.href 是否可以被伪造。
    猜你喜欢
    • 2016-06-04
    • 2012-06-21
    • 1970-01-01
    • 2023-03-26
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    相关资源
    最近更新 更多