php 防止会话劫持

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12233406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:06:23  来源:igfitidea点击:

Preventing session hiHymaning

phpsecuritysession

提问by hesson

How do you prevent multiple clients from using the same session ID? I'm asking this because I want to add an extra layer of security to prevent session hiHymaning on my website. If a hacker somehow figures out another user's session ID and makes requests with that SID, how can I detect that there are different clients sharing a single SID on the server and then reject the hiHyman attempt?

如何防止多个客户端使用相同的会话 ID?我问这个是因为我想添加一个额外的安全层来防止我的网站上的会话劫持。如果黑客以某种方式找出另一个用户的会话 ID 并使用该 SID 发出请求,我如何检测服务器上有不同的客户端共享单个 SID,然后拒绝劫持尝试?

EDIT

编辑

I have accepted Gumbo's answer after careful consideration because I've come to the realization that what I'm asking for is impossible due to the restrictions of a stateless HTTP protocol. I forgot about what is perhaps the most fundamental principle of HTTP, and now that I think about this question seems a bit trivial.

经过仔细考虑,我接受了 Gumbo 的回答,因为我已经意识到,由于无状态 HTTP 协议的限制,我的要求是不可能的。我忘记了可能是 HTTP 最基本的原则是什么,现在我想到这个问题似乎有点微不足道。

Let me elaborate what I mean:

让我详细说明我的意思:

After User A logs in on example.com, he is given some random session ID, for simplicity's sake, let it be 'abc123'. This session ID is stored as a cookie on the client side and is validated with a server-side session to ensure the user who logged in remains logged in as he moves from one webpage to another. This cookie of course would not need to exist if HTTP were not stateless. For that reason, if User B steals User A's SID, and creates a cookie on his computer with the value 'abc123', he would have successfully hiHymaned User A's session, but there is simply no way for the server to legitimately recognize that User B's request is any different from User A's requests, and therefore the server has no reason to reject any request. Even if we were to list the sessions that were already active on the server and try to see if someone is accessing a session that is already active, how can we determine that it is another user who is accessing the session illegitimately and not the same user who is already logged in with a session ID, but simply trying to make another request with it (ie navigate to a different webpage). We can't. Checking the user agent? Can be spoofed - but good as a Defense in Depth measure nevertheless. IP Address? Can change for legitimate reasons - but instead of not checking for the IP address at all, I suggest checking something like the first two octets of the IP, as even a user on a data plan network who constantly has a changing IP for perfectly legitimate reasons would only usually have the last two octets of their IP change.

用户 A 登录 example.com 后,会获得一些随机会话 ID,为简单起见,将其设为 'abc123'。此会话 ID 作为 cookie 存储在客户端,并通过服务器端会话进行验证,以确保登录的用户在从一个网页移动到另一个网页时保持登录状态。如果 HTTP 不是无状态的,这个 cookie 当然不需要存在。出于这个原因,如果用户 B 窃取了用户 A 的 SID,并在他的计算机上创建了一个值为“abc123”的 cookie,他就可以成功劫持用户 A 的会话,但是服务器根本无法合法地识别用户 B 的request 与用户 A 的请求有任何不同,因此服务器没有理由拒绝任何请求。即使我们要列出服务器上已经处于活动状态的会话并尝试查看是否有人正在访问已经处于活动状态的会话,我们如何确定非法访问会话的是另一个用户而不是同一用户谁已经使用会话 ID 登录,但只是尝试用它发出另一个请求(即导航到不同的网页)。我们不能。检查用户代理?可以被欺骗 - 但作为深度防御措施仍然很好。IP地址?可以出于合法原因进行更改 - 但与其根本不检查 IP 地址,我建议您检查 IP 的前两个八位字节之类的内容,因为即使是数据计划网络上的用户,由于完全合法的原因而不断更改 IP通常只会更改其 IP 的最后两个八位字节。

In consclusion, it is the stateless HTTP that condemns us to never being able to fully protect our websites from session hiHymaning, but good practices (like the ones Gumbo has provided) will be good enough to prevent a good majority of session attacks. Trying to protect sessions from hiHymaning by denying multiple requests of the same SID is therefore simply ludicrous, and would defeat the whole purpose of sessions.

总而言之,正是无状态 HTTP 使我们永远无法完全保护我们的网站免受会话劫持,但良好的做法(如 Gumbo 提供的做法)足以防止大部分会话攻击。因此,试图通过拒绝同一 SID 的多个请求来保护会话免遭劫持是非常荒谬的,并且会破坏会话的全部目的。

回答by Gumbo

Unfortunately, there is no effective way to unmistakably identify a request that originates from an attacker in opposite to a genuine request. Because most properties that counter measures check like the IP address or user agent characteristics are either not reliable (IP address might change among multiple requests) or can be forged easily (e. g. User-Agentrequest header) and thus can yield unwanted false positives (i. e. genuine user switched IP address) or false negatives (i. e. attacker was able to successfully forge request with same User-Agent).

不幸的是,没有有效的方法来明确无误地识别来自攻击者的请求,而不是真正的请求。因为像 IP 地址或用户代理特征这样的对抗措施检查的大多数属性要么不可靠(IP 地址可能在多个请求之间改变)要么很容易伪造(例如用户代理请求标头),因此会产生不必要的误报(即真正的用户切换 IP 地址)或漏报(即攻击者能够使用相同的User-Agent成功伪造请求)。

That's why the best method to prevent session hiHymaning is to make sure an attacker cannot find out another user's session ID. This means you should design your application and its session management that (1) an attacker cannot guess a valid session ID by using enough entropy, and (2) that there is no other way for an attacker to obtain a valid session ID by known attacks/vulerabilities like sniffing the network communication, Cross-Site Scripting, leakage through Referer, etc.

这就是为什么防止会话劫持的最佳方法是确保攻击者无法找到其他用户的会话 ID。这意味着您应该设计您的应用程序及其会话管理,(1) 攻击者无法通过使用足够的熵来猜测有效的会话 ID,以及 (2) 攻击者没有其他方法可以通过已知攻击获得有效的会话 ID / 漏洞,例如嗅探网络通信、跨站点脚本、通过Referer泄漏等。

That said, you should:

也就是说,你应该:

Besides that, you should also regenerate the session ID while invalidating the old one (see session_regenerate_idfunction) after certain session state changes (e. g. confirmation of authenticity after login or change of authorization/privileges) and you can additionally do this periodically to reduce the time span for a successful session hiHymaning attack.

除此之外,您还应该在某些会话状态更改(例如登录后确认真实性或更改授权/特权)后使旧会话 ID 无效时重新生成会话 ID(请参阅session_regenerate_id函数),并且您还可以定期执行此操作以减少时间跨度成功的会话劫持攻击。

回答by kanchan

Can we do something like this.

我们能不能做这样的事情。

Store session id in database. Also store the Ip address and the HTTP_USER_AGENT for that session id. Now when a request comes to the server containing that matching session id, Check from which agent and ip it is coming from in your script.

将会话 ID 存储在数据库中。还要存储该会话 ID 的 IP 地址和 HTTP_USER_AGENT。现在,当请求到达包含该匹配会话 ID 的服务器时,请在脚本中检查它来自哪个代理和 IP。

Can make this funda work by make common function or class for session so that every request is verified before it is processed. It would hardly take some micro seconds. But, If many users are visiting your site and you have huge database of sessions, then this might be little performance issue. But, It would surely be very secure compared o other methods like => Using regenerating sessions.

可以通过为会话创建通用函数或类来使此基础工作,以便在处理每个请求之前对其进行验证。几乎不需要几微秒。但是,如果许多用户正在访问您的站点并且您拥有庞大的会话数据库,那么这可能不是性能问题。但是,与其他方法(例如 => 使用重新生成会话)相比,它肯定会非常安全。

In regenerating session ids, there is again little chance of session hiHymaning.

在重新生成会话 ID 时,会话劫持的可能性再次很小。

suppose, user's session id is copied and that user is not working or active for sometime and no request is made to server with old session id asking to regenerate new one. Then In case session id is hiHymaned, hacker will use that session id and make request to server with that id, then server will respond back with regenerated session id and so that hacker can go on using the services. Actual user will no longer be able to operate because he is unknown of what the regenerated id is and what request session id is to be passed in request. Completely Gone.

假设,用户的会话 ID 被复制,并且该用户在一段时间内不工作或不活动,并且没有向具有旧会话 ID 的服务器发出要求重新生成新会话 ID 的请求。然后,如果会话 ID 被劫持,黑客将使用该会话 ID 并使用该 ID 向服务器发出请求,然后服务器将使用重新生成的会话 ID 进行响应,以便黑客可以继续使用这些服务。实际用户将不再能够操作,因为他不知道重新生成的 id 是什么,以及请求中传递的请求会话 id 是什么。完全消失了。

Please correct me if i m wrong somewhere.

如果我在某处错了,请纠正我。

回答by Manjeet Kumar Nai

Session hiHymaning is a serious threat, it has to handle by using a secure socket layer for advanced application which involves transactions or by using simple techniques like using cookies, session timeouts and regenerates id etc as explained above.
When the internet was born, HTTP communications were designed to be stateless; that is, a connection between two entities exists only for the brief period of time required for a request to be sent to the server, and the resulting response passed back to the client. Here are a few methods which hackers follow to hiHyman the session

会话劫持是一个严重的威胁,它必须通过对涉及事务的高级应用程序使用安全套接字层或通过使用简单的技术(如使用 cookie、会话超时和重新生成 id 等)来处理,如上所述。
互联网诞生时,HTTP 通信被设计为无状态的;也就是说,两个实体之间的连接仅在将请求发送到服务器所需的短暂时间段内存在,并将结果响应传递回客户端。以下是黑客劫持会话的几种方法

  • Network Eavesdropping
  • Unwitting Exposure
  • Forwarding, Proxies, and Phishing
  • Reverse Proxies
  • 网络窃听
  • 不知情的曝光
  • 转发、代理和网络钓鱼
  • 反向代理

Always recommend SSL Secure Sockets Layer
Use cookiesalso to following ini_set() directives at the start of your scripts, in order to override any global settings in php.ini:

始终推荐 SSL安全套接字层在脚本开始时也
使用cookie来遵循 ini_set() 指令,以便覆盖 php.ini 中的任何全局设置:

ini_set( 'session.use_only_cookies', TRUE );                
ini_set( 'session.use_trans_sid', FALSE );

Use Session Timeouts and Session Regenerate ID

使用会话超时和会话重新生成 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
?>

回答by Lèse majesté

There are lots of standard defenses against session hiHymaning. One of them is to match each session to a single IP address.

针对会话劫持的标准防御措施有很多。其中之一是将每个会话与单个 IP 地址匹配。

Other schemesmay use an HMAC generated from:

其他方案可能会使用从以下位置生成的 HMAC:

  • the network address of the client's IP
  • the user-agent header sent by the client
  • the SID
  • a secret key stored on the server
  • 客户端IP的网络地址
  • 客户端发送的用户代理标头
  • SID
  • 存储在服务器上的密钥

The reason only the network address of the IP is used is in case the user is behind a public proxy, in which case their IP address can change with each request, but the network address remains the same.

仅使用 IP 的网络地址的原因是,如果用户位于公共代理后面,在这种情况下,他们的 IP 地址可以随着每个请求而改变,但网络地址保持不变。

Of course, to truly be secure, you really ought to force SSL for all requests so that the SID can't be intercepted by would-be attackers in the first place. But not all sites do this (::cough:: Stack Overflow::cough::).

当然,要真正确保安全,您确实应该对所有请求强制使用 SSL,这样 SID 就不会首先被潜在的攻击者拦截。但并非所有网站都这样做(::cough:: Stack Overflow::cough::)。

回答by Sk MiRaj

In my view you can store session id in database when users login and check everyone for the same before loggin in. delete the same session id which you have stored in database when users logout. You can easily findout session id of each and every user or else I can help you.

在我看来,您可以在用户登录时将会话 ID 存储在数据库中,并在登录前检查每个人是否相同。删除用户注销时存储在数据库中的相同会话 ID。您可以轻松找到每个用户的会话 ID,否则我可以帮助您。

回答by Ratan Kumar

One of the easy implementations can be done by making a table in database , as logged users , then at login, update that table with user name and his SID , this will prevent other logins as same user , now at the time of log out , just run a simple query , which deletes the logged in data in database , this can also be used to trace logged in user on ur website at a time .

一个简单的实现可以通过在数据库中创建一个表来完成,作为登录用户,然后在登录时,使用用户名和他的 SID 更新该表,这将防止其他用户以同一用户身份登录,现在在注销时,只需运行一个简单的查询,它会删除数据库中的登录数据,这也可以用于一次跟踪您网站上的登录用户。

回答by kanchan

Obviously when you'll set session cookie in the browser, that cookie is sent in the request. Now when request comes, Server will check the session id in database and grant access. To prevent that only its important to store agent and ip so that before checking server makes sure that sessions access is granted to the unique client and not the unique session id which can be hiHymaned.

显然,当您在浏览器中设置会话 cookie 时,该 cookie 将在请求中发送。现在,当请求到来时,服务器将检查数据库中的会话 ID 并授予访问权限。为了防止仅存储代理和 IP 很重要,以便在检查服务器之前确保将会话访问权限授予唯一的客户端,而不是可以劫持的唯一会话 ID。

回答by Anandu M Das

I don't know about the coding part well. So I can tell u an algorithm to do this. Setting stuffs like SSL, or setting the session cookie to secure and httpOnly wont work if a user sniffs the session id from a LAN network(Provided user and attacker are in the same LAN).

我不太了解编码部分。所以我可以告诉你一个算法来做到这一点。如果用户从 LAN 网络嗅探会话 ID(假设用户和攻击者在同一个 LAN 中),则设置 SSL 之类的内容,或将会话 cookie 设置为安全和 httpOnly 将不起作用。

So what you can do is, once the user successfully logs into the application, set unique token to each and every pages of the web application and keep a track of this at the server side. So that if the valid user sends the request to access a particular page, the token of that page will also be sent to the server side. Since the tokens are unique for a user for a particular session, even if the attacker can get the session id, he cannot hiHyman the users session as he cannot provide the valid token to the server.

所以你可以做的是,一旦用户成功登录到应用程序,为 Web 应用程序的每个页面设置唯一的令牌,并在服务器端进行跟踪。这样如果有效用户发送访问特定页面的请求,该页面的令牌也会被发送到服务器端。由于令牌对于特定会话的用户是唯一的,即使攻击者可以获得会话 ID,他也无法劫持用户会话,因为他无法向服务器提供有效令牌。

回答by user253780

@Anandu M Das:

@Anandu M Das:

I believe what you may be referring to is the use of session tokens with each session ID. This site can explain the use of tokens with sessions:

我相信您可能指的是在每个会话 ID 中使用会话令牌。该站点可以解释令牌与会话的使用:

https://blog.whitehatsec.com/tag/session-token/

https://blog.whitehatsec.com/tag/session-token/

Although session tokens are easily compromised by an XSS attack, this doesn't mean that they should never be used. I mean let's face it, if something was compromisable by a security vulnerability on the server, its not the fault of the method, its the fault of the programmer who introduced that vulnerability (to highlight points made by Hesson and Rook).

尽管会话令牌很容易被 XSS 攻击破坏,但这并不意味着它们永远不应该被使用。我的意思是让我们面对现实,如果服务器上的安全漏洞可以破坏某些东西,这不是方法的错,而是引入该漏洞的程序员的错(强调 Hesson 和 Rook 提出的观点)。

If you follow proper security conventions and practicies and secure your site from SQL injection, XSS, and require all sessions be managed over HTTPS, then you can easily manage the potential attack from CSRF by use of server-side tokens, stored within the session, and updated everytime the user would cause a manipulation to their session (like a $_POST being submitted). Also, NEVER store sessions or their contents in a url, no matter how well you think they are encoded.

如果您遵循适当的安全约定和实践并保护您的站点免受 SQL 注入、XSS 的侵害,并要求通过 HTTPS 管理所有会话,那么您可以通过使用存储在会话中的服务器端令牌轻松管理来自 CSRF 的潜在攻击,并在每次用户对其会话进行操作时进行更新(例如提交 $_POST)。此外,永远不要将会话或其内容存储在 url 中,无论您认为它们的编码有多好。

When the security of your users is paramount (which it should be), the use of session tokens will allow better or more advanced functionality to be provided without compromising their session security.

当您的用户的安全性是最重要的(应该是)时,会话令牌的使用将允许提供更好或更高级的功能,而不会影响他们的会话安全性。