PHP会话变量有多安全?

时间:2022-09-20 11:08:50

I have a login script that verifies a username/password against data in a 'user' table. Furthermore, I have a 'roles' table that specifies the access level of a given user. Assuming I am using safe login scripts, are there any security holes in simply performing an additional query, upon successful login, against the 'roles' table to discover the user's authorization level and storing this into a session variable? The idea would then be that on any page with mixed authority, I could simply query the session variable to discover the logged in user's authorization level.

我有一个登录脚本,可以在“用户”表中验证用户名/密码。此外,我有一个“role”表,指定给定用户的访问级别。假设我使用的是安全的登录脚本,那么在成功登录后对“roles”表执行额外的查询以发现用户的授权级别并将其存储到会话变量中,是否存在安全漏洞呢?这样的想法是,在任何具有混合权限的页面上,我都可以简单地查询会话变量来发现登录用户的授权级别。

Thanks.

谢谢。

4 个解决方案

#1


71  

Sessions are significantly safer than, say, cookies. But it is still possible to steal a session and thus the hacker will have total access to whatever is in that session. Some ways to avoid this are IP Checking (which works pretty well, but is very low fi and thus not reliable on its own), and using a nonce. Typically with a nonce, you have a per-page "token" so that each page checks that the last page's nonce matches what it has stored.

会话要比饼干安全得多。但是仍然有可能窃取会话,因此黑客可以完全访问会话中的任何内容。避免这种情况的一些方法是IP检查(它工作得很好,但是它的fi很低,因此本身不可靠)和使用nonce。通常,对于nonce,您有一个每个页面的“标记”,以便每个页面检查最后一个页面的nonce是否与它存储的内容匹配。

In either security check, there is a loss of usability. If you do IP checking and the user is behind a intranet firewall (or any other situation that causes this) which doesn't hold a steady IP for that user, they will have to re-authenticate every time they lose their IP. With a nonce, you get the always fun "Clicking back will cause this page to break" situation.

在任何一种安全检查中,都存在可用性损失。如果您进行IP检查,而用户位于内部网防火墙(或导致这种情况的任何其他情况)后面,而该防火墙没有为该用户保存稳定的IP,那么每次丢失IP时,他们都必须重新进行身份验证。有了nonce,你就得到了“点击返回将导致这个页面崩溃”的乐趣。

But with a cookie, a hacker can steal the session simply by using fairly simple XSS techniques. If you store the user's session ID as a cookie, they are vulnerable to this as well. So even though the session is only penetrable to someone who can do a server-level hack (which requires much more sophisticated methods and usually some amount of privilege, if your server is secure), you are still going to need some extra level of verification upon each script request. You should not use cookies and AJAX together, as this makes it a tad easier to totally go to town if that cookie is stolen, as your ajax requests may not get the security checks on each request. For example, if the page uses a nonce, but the page is never reloaded, the script may only be checking for that match. And if the cookie is holding the authentication method, I can now go to town doing my evilness using the stolen cookie and the AJAX hole.

但是有了cookie,黑客只需使用相当简单的XSS技术就可以窃取会话。如果您将用户的会话ID存储为cookie,那么它们也很容易受到攻击。因此,即使会话只对能够执行服务器级攻击(这需要更复杂的方法,通常还需要一些特权,如果您的服务器是安全的)的人有效,您仍然需要对每个脚本请求进行额外的验证。您不应该同时使用cookie和AJAX,因为如果cookie被盗,那么完全转移到镇上就会容易一些,因为您的AJAX请求可能不会对每个请求进行安全检查。例如,如果页面使用了nonce,但是页面永远不会重新加载,脚本可能只会检查该匹配。如果cookie持有身份验证方法,那么我现在就可以使用偷来的cookie和AJAX漏洞来做坏事了。

#2


16  

Only scripts executing on your server have access to the _SESSION array. If you define the scope of the session cookie, you can even restrict it to a specific directory. The only way someone besides you could get that session data is to inject some PHP code into one of your pages.

只有在服务器上执行的脚本才能访问_SESSION数组。如果您定义了会话cookie的范围,您甚至可以将它限制在特定的目录中。除了您之外,获得会话数据的唯一方法是将一些PHP代码注入您的一个页面。

As for the system you're using, that is acceptable and is a good way to save database calls, but keep in mind that it will require the user to log out and log in again for any authorization changes to apply. So if you wanted to lock out an account and that user is already logged in, you can't.

对于您正在使用的系统,这是可以接受的,并且是保存数据库调用的好方法,但是请记住,它将要求用户退出并再次登录,以便应用任何授权更改。因此,如果你想锁定一个帐户,而那个用户已经登录了,你就不能。

#3


13  

It should be noted that in Apache the PHP $_SESSION superglobal is accessible across virtualhosts. Consider this scenario:

应该注意的是,在Apache中,PHP $_SESSION超全局变量可以跨虚拟主机访问。考虑一下这个场景:

  • Your server hosts two domains, example.com and instance.org. PHP sessions are stored in cookies that are restricted to the domain.
  • 您的服务器托管两个域,example.com和instance.org。PHP会话存储在仅限于域的cookie中。
  • A user logs in to example.com and receives a session ID. Example.com sets some session variables (which are stored on the server, not in the cookie).
  • 用户登录到example.com并接收会话ID. example.com设置一些会话变量(它们存储在服务器上,而不是cookie中)。
  • A third party intercepts the cookie during transmission and passes it to instance.org. Instance.org now has access to the example.com session variables.
  • 第三方在传输过程中截获cookie并将其传递给instance.org。Instance.org现在可以访问example.com会话变量。

This is not such a big deal when you control all the virtualhosts on your server, but if you are on a shared machine, it's problematic.

当您控制服务器上的所有虚拟主机时,这并不是什么大问题,但是如果您在共享机器上,这就有问题了。

#4


2  

If you rely on a value stored inside of a session variable to determine roles then you lose the ability to change the value in the DB and have it reflected against the user's current session. If you look at Zend Framework, there's a clear distinction between authentication and authorization, and strongly-worded warnings in the manual to only store the minimal amount of data in the session (ie "Yup, he's user #37 & he logged in").

如果您依赖于一个会话变量内存储的值来确定角色,那么您就失去了更改DB中的值并将其反映到用户当前会话的能力。如果您查看Zend框架,您会发现身份验证和授权之间有明显的区别,并且手册中措辞强硬的警告只存储会话中最少的数据(例如“是的,他是用户#37 &他登录了”)。

As far as 'safety' goes - unless you're on shared host, there's nothing to worry about. On a properly configured shared host, they should be relatively secure, too.

至于“安全”,除非你是在共享主机上,否则没什么好担心的。在正确配置的共享主机上,它们也应该相对安全。

#1


71  

Sessions are significantly safer than, say, cookies. But it is still possible to steal a session and thus the hacker will have total access to whatever is in that session. Some ways to avoid this are IP Checking (which works pretty well, but is very low fi and thus not reliable on its own), and using a nonce. Typically with a nonce, you have a per-page "token" so that each page checks that the last page's nonce matches what it has stored.

会话要比饼干安全得多。但是仍然有可能窃取会话,因此黑客可以完全访问会话中的任何内容。避免这种情况的一些方法是IP检查(它工作得很好,但是它的fi很低,因此本身不可靠)和使用nonce。通常,对于nonce,您有一个每个页面的“标记”,以便每个页面检查最后一个页面的nonce是否与它存储的内容匹配。

In either security check, there is a loss of usability. If you do IP checking and the user is behind a intranet firewall (or any other situation that causes this) which doesn't hold a steady IP for that user, they will have to re-authenticate every time they lose their IP. With a nonce, you get the always fun "Clicking back will cause this page to break" situation.

在任何一种安全检查中,都存在可用性损失。如果您进行IP检查,而用户位于内部网防火墙(或导致这种情况的任何其他情况)后面,而该防火墙没有为该用户保存稳定的IP,那么每次丢失IP时,他们都必须重新进行身份验证。有了nonce,你就得到了“点击返回将导致这个页面崩溃”的乐趣。

But with a cookie, a hacker can steal the session simply by using fairly simple XSS techniques. If you store the user's session ID as a cookie, they are vulnerable to this as well. So even though the session is only penetrable to someone who can do a server-level hack (which requires much more sophisticated methods and usually some amount of privilege, if your server is secure), you are still going to need some extra level of verification upon each script request. You should not use cookies and AJAX together, as this makes it a tad easier to totally go to town if that cookie is stolen, as your ajax requests may not get the security checks on each request. For example, if the page uses a nonce, but the page is never reloaded, the script may only be checking for that match. And if the cookie is holding the authentication method, I can now go to town doing my evilness using the stolen cookie and the AJAX hole.

但是有了cookie,黑客只需使用相当简单的XSS技术就可以窃取会话。如果您将用户的会话ID存储为cookie,那么它们也很容易受到攻击。因此,即使会话只对能够执行服务器级攻击(这需要更复杂的方法,通常还需要一些特权,如果您的服务器是安全的)的人有效,您仍然需要对每个脚本请求进行额外的验证。您不应该同时使用cookie和AJAX,因为如果cookie被盗,那么完全转移到镇上就会容易一些,因为您的AJAX请求可能不会对每个请求进行安全检查。例如,如果页面使用了nonce,但是页面永远不会重新加载,脚本可能只会检查该匹配。如果cookie持有身份验证方法,那么我现在就可以使用偷来的cookie和AJAX漏洞来做坏事了。

#2


16  

Only scripts executing on your server have access to the _SESSION array. If you define the scope of the session cookie, you can even restrict it to a specific directory. The only way someone besides you could get that session data is to inject some PHP code into one of your pages.

只有在服务器上执行的脚本才能访问_SESSION数组。如果您定义了会话cookie的范围,您甚至可以将它限制在特定的目录中。除了您之外,获得会话数据的唯一方法是将一些PHP代码注入您的一个页面。

As for the system you're using, that is acceptable and is a good way to save database calls, but keep in mind that it will require the user to log out and log in again for any authorization changes to apply. So if you wanted to lock out an account and that user is already logged in, you can't.

对于您正在使用的系统,这是可以接受的,并且是保存数据库调用的好方法,但是请记住,它将要求用户退出并再次登录,以便应用任何授权更改。因此,如果你想锁定一个帐户,而那个用户已经登录了,你就不能。

#3


13  

It should be noted that in Apache the PHP $_SESSION superglobal is accessible across virtualhosts. Consider this scenario:

应该注意的是,在Apache中,PHP $_SESSION超全局变量可以跨虚拟主机访问。考虑一下这个场景:

  • Your server hosts two domains, example.com and instance.org. PHP sessions are stored in cookies that are restricted to the domain.
  • 您的服务器托管两个域,example.com和instance.org。PHP会话存储在仅限于域的cookie中。
  • A user logs in to example.com and receives a session ID. Example.com sets some session variables (which are stored on the server, not in the cookie).
  • 用户登录到example.com并接收会话ID. example.com设置一些会话变量(它们存储在服务器上,而不是cookie中)。
  • A third party intercepts the cookie during transmission and passes it to instance.org. Instance.org now has access to the example.com session variables.
  • 第三方在传输过程中截获cookie并将其传递给instance.org。Instance.org现在可以访问example.com会话变量。

This is not such a big deal when you control all the virtualhosts on your server, but if you are on a shared machine, it's problematic.

当您控制服务器上的所有虚拟主机时,这并不是什么大问题,但是如果您在共享机器上,这就有问题了。

#4


2  

If you rely on a value stored inside of a session variable to determine roles then you lose the ability to change the value in the DB and have it reflected against the user's current session. If you look at Zend Framework, there's a clear distinction between authentication and authorization, and strongly-worded warnings in the manual to only store the minimal amount of data in the session (ie "Yup, he's user #37 & he logged in").

如果您依赖于一个会话变量内存储的值来确定角色,那么您就失去了更改DB中的值并将其反映到用户当前会话的能力。如果您查看Zend框架,您会发现身份验证和授权之间有明显的区别,并且手册中措辞强硬的警告只存储会话中最少的数据(例如“是的,他是用户#37 &他登录了”)。

As far as 'safety' goes - unless you're on shared host, there's nothing to worry about. On a properly configured shared host, they should be relatively secure, too.

至于“安全”,除非你是在共享主机上,否则没什么好担心的。在正确配置的共享主机上,它们也应该相对安全。