如何防止多个客户端使用相同的会话ID?我问这个是因为我想添加额外的安全层来防止我网站上的会话劫持。如果黑客以某种方式计算出另一个用户的会话ID并使用该SID发出请求,我如何检测到服务器上有不同的客户端共享一个SID然后拒绝劫持尝试?
修改
我仔细考虑后接受了Gumbo的回答,因为我已经意识到由于无状态HTTP协议的限制,我所要求的是不可能的。我忘记了HTTP的最基本原则是什么,现在我认为这个问题似乎有点微不足道。
让我详细说明我的意思:
在用户A登录example.com后,他会获得一些随机会话ID,为简单起见,请将其设为'abc123'。此会话ID在客户端存储为cookie,并通过服务器端会话进行验证,以确保登录的用户在从一个网页移动到另一个网页时仍然登录。如果HTTP不是无状态的,那么当然不需要存在这个cookie。因此,如果用户B窃取用户A的SID,并在其计算机上创建一个值为'abc123'的cookie,他就会成功劫持用户A的会话,但服务器根本无法合法地识别用户B的请求与用户A的请求有任何不同,因此服务器没有理由拒绝任何请求。即使我们要列出已经在服务器上处于活动状态的会话并尝试查看是否有人正在访问已经处于活动状态的会话,我们如何确定它是另一个非法访问会话的用户而不是同一个用户谁已经使用会话ID登录,但只是尝试用它发出另一个请求(即导航到不同的网页)。我们做不到。检查用户代理?可以欺骗 - 尽管如此,作为深度防御措施还是很好的。 IP地址?可以出于正当理由进行更改 - 但是我没有根本不检查IP地址,而是建议检查IP的前两个八位字节,甚至是数据计划网络中的用户,因为完全合法的原因,他们经常拥有不断变化的IP通常只有IP更改的最后两个八位字节。
在结论中,无状态HTTP谴责我们永远无法完全保护我们的网站免受会话劫持,但良好实践(如Gumbo提供的那些)将足以防止大多数会话攻击。因此,试图通过拒绝相同SID的多个请求来保护会话免遭劫持是荒谬的,并且会破坏会话的整个目的。
答案 0 :(得分:74)
不幸的是,没有有效的方法可以明确地识别出来自与真实请求相反的攻击者的请求。因为大多数反对措施检查的属性(如IP地址或用户代理特征)要么不可靠(IP地址可能在多个请求之间更改),要么可以轻松伪造(例如 User-Agent 请求标头),因此可以产生不必要的误报(即真正的用户交换IP地址)或漏报(即攻击者能够使用相同的 User-Agent 成功伪造请求。)
这就是为什么防止会话劫持的最佳方法是确保攻击者无法找到其他用户的会话ID。这意味着您应该设计应用程序及其会话管理:(1)攻击者无法通过使用足够的熵来猜测有效的会话ID,以及(2)攻击者没有其他方法可以通过已知攻击获取有效的会话ID / vulerabilities,如嗅探网络通信,跨站点脚本,通过 Referer 泄漏等。
那就是说,你应该:
HttpOnly
和Secure
属性设置Cookie以禁止通过JavaScript访问(如果是XSS漏洞)并禁止通过不安全通道进行传输(请参阅session.cookie_httponly和{{3 }})除此之外,您还应该重新生成会话ID,同时在某些会话状态更改(例如,登录后确认真实性或更改授权/权限)后使旧会话ID无效(请参阅session.cookie_secure),您还可以执行此操作这会定期减少成功的会话劫持攻击的时间跨度。
答案 1 :(得分:4)
我们可以这样做吗。
将会话ID存储在数据库中。 还存储该会话ID的IP地址和HTTP_USER_AGENT。 现在,当请求到达包含该匹配会话ID的服务器时,请检查脚本中来自哪个代理和IP。
可以通过为会话制作通用函数或类来使这个基础工作,以便在处理之前验证每个请求。它几乎不需要一些微秒。但是,如果许多用户正在访问您的站点并且您拥有庞大的会话数据库,那么这可能是一个很小的性能问题。但是,与其他方法相比,它肯定会非常安全 =>使用重新生成会话。
在重新生成会话ID时,会话劫持的可能性很小。
假设,用户的会话ID被复制,并且该用户有时没有工作或活动,并且没有请求具有旧会话ID的服务器要求重新生成新会话ID。然后,如果会话ID被劫持,黑客将使用该会话ID并向具有该id的服务器发出请求,然后服务器将使用重新生成的会话ID进行响应,以便黑客可以继续使用该服务。实际用户将无法再操作,因为他不知道重新生成的ID是什么以及请求会话ID将在请求中传递。完全走了。
如果我错了,请纠正我。
答案 2 :(得分:2)
有许多针对会话劫持的标准防御措施。其中之一是将每个会话匹配到一个IP地址。
Other schemes可能会使用从以下位置生成的HMAC:
仅使用IP的网络地址的原因是用户位于公共代理服务器后面,在这种情况下,他们的IP地址可能随每个请求而变化,但网络地址保持不变。
当然,为了真正安全,你真的应该为所有请求强制使用SSL,这样SID就不会被潜在的攻击者拦截。但并非所有网站都这样做( :: cough :: Stack Overflow :: cough :: )。
答案 3 :(得分:1)
在我看来,您可以在用户登录时将会话ID存储在数据库中,并在登录之前检查每个人的相同内容。删除用户注销时存储在数据库中的相同会话ID。您可以轻松找到每个用户的会话ID,否则我可以帮助您。
答案 4 :(得分:1)
其中一个简单的实现可以通过在数据库中创建一个表,作为已登录的用户,然后在登录时,使用用户名和他的SID更新该表,这将阻止其他登录为同一用户,现在在注销,只需运行一个简单的查询,删除数据库中登录的数据,这也可以用来跟踪你网站上登录的用户。
答案 5 :(得分:1)
显然,当您在浏览器中设置会话cookie时,该cookie将在请求中发送。现在,当请求到来时,Server将检查数据库中的会话ID并授予访问权限。为了防止这只是重要的存储代理和IP,以便在检查服务器之前确保会话访问被授予唯一客户端而不是可以被劫持的唯一会话ID。
答案 6 :(得分:0)
我不太了解编码部分。所以我可以告诉你一个算法来做到这一点。如果用户从LAN网络嗅探会话ID(提供的用户和攻击者在同一个LAN中),则设置SSL之类的内容,或将会话cookie设置为安全,httpOnly将无法工作。
因此,您可以做的是,一旦用户成功登录到应用程序,就会为Web应用程序的每个页面设置唯一标记,并在服务器端跟踪这一点。因此,如果有效用户发送访问特定页面的请求,则该页面的令牌也将被发送到服务器端。由于令牌对于特定会话的用户是唯一的,即使攻击者可以获得会话ID,他也不能劫持用户会话,因为他无法向服务器提供有效令牌。
答案 7 :(得分:0)
@Anandu M Das:
我相信你可能指的是会话令牌与每个会话ID的使用。该站点可以解释令牌与会话的使用:
https://blog.whitehatsec.com/tag/session-token/
虽然会话令牌很容易受到XSS攻击的影响,但这并不意味着它们永远不会被使用。我的意思是让我们面对它,如果某些事情可以被服务器上的安全漏洞所破坏,那不是方法的错,它是引入该漏洞的程序员的错(为了突出Hesson和Rook提出的点)。
如果您遵循正确的安全约定和实践并保护您的站点免受SQL注入,XSS的攻击,并要求所有会话都通过HTTPS进行管理,那么您可以通过使用存储在服务器端的令牌来轻松管理来自CSRF的潜在攻击每次用户都会对其会话进行操作(如提交的$ _POST),会话和更新。此外,永远不要将会话或其内容存储在网址中,无论您认为它们的编码程度如何。
当用户的安全性至关重要时(应该是这样),会话令牌的使用将允许提供更好或更高级的功能,而不会影响他们的会话安全性。
答案 8 :(得分:0)
会话劫持是一个严重的威胁,它必须通过对涉及事务的高级应用程序使用安全套接字层或使用简单的技术(例如使用cookie,会话超时和重新生成ID等)来进行处理,如上所述。
互联网诞生时,HTTP通信被设计为无状态的。也就是说,两个实体之间的连接仅在将请求发送到服务器所需的短暂时间内存在,并且结果响应被传递回客户端。
黑客遵循以下几种方法劫持会话
始终建议使用SSL 安全套接字层
还可以使用 cookies 在脚本开始时遵循ini_set()指令,以覆盖php.ini中的所有全局设置:
ini_set( 'session.use_only_cookies', TRUE );
ini_set( 'session.use_trans_sid', FALSE );
使用会话超时和会话重新生成ID
<?php
// regenerate session on successful login
if ( !empty( $_POST['password'] ) && $_POST['password'] === $password )
{
// if authenticated, generate a new random session ID
session_regenerate_id();
// set session to authenticated
$_SESSION['auth'] = TRUE;
// redirect to make the new session ID live
header( 'Location: ' . $_SERVER['SCRIPT_NAME'] );
}
// take some action
?>