我目前拥有自己的应用程序安全服务,该服务在我的企业中运行,并且 - 在很大程度上 - 满足业务需求.
我目前面临的问题是,该服务传统上(天真地)依赖于用户的源IP保持不变作为对抗会话劫持的对冲 - 企业中的Web应用程序不能直接向公众提供,并且它过去是完美的我可以要求用户的地址在给定的会话期间保持不变.
不幸的是,情况已不再如此,因此我不得不切换到不依赖源IP的解决方案.我更倾向于实现一个实际完成原始设计者意图的解决方案(即防止会话劫持).
到目前为止,我的研究已经出现了这个问题,其实质上是"用SSL会话密钥加密你的身份验证令牌哈希".
从表面上看,这似乎是一个完美的解决方案,但我仍然怀疑这个方案的实际实施是不切实际的,因为客户端和服务器可能在任何时候 - 有效地任意 - 选择重新协商SSL会话,从而更改密钥.
这是我想象的场景:
SSL会话建立并且密钥达成一致.
客户端在应用程序级别对服务器进行身份验证(即通过用户名和密码).
服务器编写包含SSL会话密钥的安全cookie.
会发生导致会话重新协商的事情.例如,我认为IE在有或没有理由的计时器上执行此操作.
客户端向包含旧会话密钥的服务器提交请求(因为没有应用程序级别的重新协商知识,所以没有机会将新的,更新的散列写入客户端).
由于哈希匹配失败等原因,服务器拒绝客户端的凭证.
这是一个真正的问题,还是由于(至少可以说)对SSL的工作方式不太完美的理解,这是我的误解?
查看与SSL持久性相关的所有主题.这是负载均衡器领域中一个经过深入研究的问题.
简短的回答是:您不能依赖SSLID - 大多数浏览器重新协商,您仍然必须使用源IP.如果IP地址是可能改变中期会议,那么你可以强制软重认证,或使用SSLID作为两个IP变化(反之亦然之间的桥梁,即只承担劫持如果两个 IP地址和SSLID变化在同时,如服务器所见.)
2014年更新
只需强制使用https
并确保您不会受到会话固定或CRIME的攻击.不要费心用任何客户端信息来限制你的身份验证令牌,因为如果攻击者能够获得令牌(前提是所述令牌不是一般的猜测),那么无论使用什么方法来获取它(例如跨站点脚本),或客户端系统的完全妥协)也将允许攻击者轻松获取可能已进入令牌的任何客户端信息(并在需要时复制辅助系统上的那些信息).
如果客户端可能只从少数几个系统连接,那么您可以在浏览器中为客户端连接的每个新客户端系统生成一个RSA密钥对(公共部分提交到您的服务器,私有部分保留在什么是有希望的安全客户端存储)并重定向到使用双向(对等/客户端证书)验证代替基于密码的身份验证的虚拟主机.