我一直在研究类似于stackexchange的身份验证和授权模块。现在,我确定他们使用某种特定的oAuth模型或授权对其各个站点使用的 token 生成服务器。我尝试了一个小实验。

登录Stackoverflow后,我将从开发人员控制台中删除所有cookie。

我保持本地存储对象完整,其中包含用于stackoverflow域的关键se:fkey xxxxxxxxxxxxxxxxxxxxxxxxx

还有一个用于stackauth域GlobalLogin: xxxxxxxxxxxxxxxxxxxxxxx的 key

se.fkey(如果我用于 session 劫持),则没有任何 react 。但是GlobalLogin可以复制并劫持我的 session 。因此,我的查询将是S/O如何处理每个站点的授权后验证。另外,是否有一种方法可以使globalLogin一次使用后失效?

{EDIT1}

因此,仅globalLogin就足够了。如果您可以获取该 key ,只需打开一个私有(private)浏览实例。在登录页面中时,在用于stackauth的Localstorage中,创建key-value映射并刷新页面。您将登录。

{EDIT2}
globalLogin key 在多个 session 中似乎是一致的。已经过了一天,我的globalLogin key 没有刷新。可以放心地假设,如果您的 key 被劫持,攻击者将无限期地访问您的个人资料。

{EDIT3}

对于正在投票并且将投票给该问题而不是与编程相关的问题的所有人。让我这样说,我们如何通过本地存储将SSO安全地存储在Web浏览器中,并且由于它们容易受到破坏,我们需要采取什么措施来防止它发生?我的一位同事很体贴,可以给我他的GlobalLogin key ,尽管它位于同一网络上,但我能够从另一台计算机上劫持他的 session 。

PS:这纯粹是出于理论理解,我是这样做的。

最佳答案

好吧,我们不看漏洞,而是看可能的攻击媒介。我将在此处添加一个表作为TL/DR

Attacker      | Vulnerable?
Eavesdropper  | Yes
MITM          | Yes
Local Attack  | Yes
Server Attack | Yes

是的,这是一个问题。

远程攻击者,可以观察流量,但不能修改流量

认为这是咖啡店中的被动攻击者。他们可以看到所有TCP级别的流量。

到SO的来回请求默认情况下未加密。您可以通过HTTPS浏览,但默认情况下仅HTTP。

因此,攻击者可以查看经过的所有请求,然后检查/窃取数据。

因此,让我们看看GlobalLogin token 是否曾经在请求中发送过...

事实上,确实如此。在登录页面上,请求通过iframe发送到以下网址:
https://stackauth.com/auth/global/read?request=//snip//

该URL返回一个脚本:
var data = {
    "ReadSession":"https://stackauth.com/auth/global/read-session",
    "Request":"//snip//",
    "Nonce":"//snip//",
    "Referrer":"//snip//",
    "StorageName":"GlobalLogin"
};

var toMsg = window.parent;
var obj = localStorage.getItem(data.StorageName);

if(obj != null) {
    var req = new XMLHttpRequest();
    req.open(
        'POST',
            data.ReadSession+
            'request='+encodeURIComponent(data.Request)+
            '&nonce='+encodeURIComponent(data.Nonce)+
            '&seriesAndToken='+encodeURIComponent(obj),
        false
    );
    req.send(null);

    if(req.status == 200){
        toMsg.postMessage(req.responseText, data.Referrer);
    }else{
        toMsg.postMessage('No Session', data.Referrer);
    }
}else{
    toMsg.postMessage('No Local Storage', data.Referrer);
}

现在,请注意GlobalLogin通过HTTPS发送到服务器。因此,可以读取流量的远程攻击者将无法获得GlobalLogin token 。

因此,GlobalLogin部分对于窃听者是安全的。

但是,请注意,由于它是通过HTTP发送的,因此仍然很容易嗅探 session cookie。

远程攻击者,可以修改流量(MITM)

好吧,这是有趣的地方。

如果您可以修改流量,那么您可以做一些非常有趣的事情。

初始页面会创建一个iframe,并通过HTTPS引入上述stackauth.com URL。好吧,如果您可以修改初始页面(也可以通过XSS进行修改),则可以将请求降级为HTTP。

而StackAuth.com将会很好。当它向stackauth.com发出请求时,您也需要拦截该请求,并将其ReadSession URL也更改为HTTP。

但是,接下来,您需要做的就是观看对ReadSession URL的调用,然后繁荣发展,您就已经盗走了GlobalLogin token 。

但是无论如何,流量都是HTTP,因此没关系,因为您无需费劲就可以窃取Cookie。那为什么要打扰呢?

本地攻击者

如果此人有权访问计算机以读取本地存储文件,则他们所做的 FAR 比仅窃取您的登录 token 更糟。

有一种称为“中间的浏览器”的攻击,其中浏览器中的漏洞使得攻击者可以执行他们想要的任何事情。

除了尝试确保浏览器的安全性之外,没有其他有效的保护措施(从头开始您无能为力)。

因此,如果攻击者可以本地访问计算机,那么游戏就结束了。

基于服务器的攻击者

如果攻击者可以访问StackOverflow的服务器,那么无论如何它都是游戏。

结论

只要允许HTTP(因为MITM始终可以将连接降级为HTTP),就没有什么可保护的,因为 session secret 始终可以通过窃听来窃取。

保护此信息的唯一方法是使用HSTS并在所有位置强制使用HTTPS。

值得注意的是,您可以通过在stackauth.com上强制使用HSTS来保护GlobalLogin,从而使主站点可以通过HTTP访问。这不会阻止攻击( session 劫持)的影响。但是它将保护一个向量。

但是,仅在任何地方通过HSTS进行HTTPS都是预防此类问题的最佳方法,而且实际上是唯一的方法。枪伤可能是创可贴。

注意:在发布之前,我确实与SO进行过交谈。

关于javascript - Stackoverflow使用本地存储进行授权似乎是不安全的。这是正确的,否则我们如何加强它?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26891083/

10-12 12:57