1

我正在制作的应用程序要求用户在登录时根据他们的用户类型和权限获取不同的内容。在登录时从他们那里检索到的信息将需要跨多个页面。

我的想法是创建一个名为“用户”的类,在登录时创建一个实例,使用数据库设置其所有属性,然后将 $_SESSION 设置为此对象,以便可以通过网站访问它以创建所需的显示。

这是一种适当且安全的做法吗?

4

1 回答 1

3

与往常一样,实施细节最重要。一般来说,使用会话来保持与用户登录会话相关的状态是可以的,实际上,这就是会话的目的。但是,有一些警告。

对象和序列化

任何时候你在会话中存储一个对象,它都会被序列化,而你读回它的任何时候,它都会被反序列化。这适用于简单的值对象,但如果您的类包含文件或数据库链接引用等内容,则可能不起作用。在最坏的情况下和特殊情况下,这甚至可能导致安全问题,但实际上不太可能发生。但是序列化本身可能很容易在某些对象上失败。

会话存储

您的会话存储有多种选择。它可以是您的应用程序/Web 服务器内存,您的服务器可以将会话内容保存到文件中,或者将它们存储在 SQL 或 NoSQL 数据库中等。对会话存储的访问控制是关键,任何有权访问会话存储的人都可以修改会话任何用户的内容。比如 Redis 经常用于存储 session 数据,但是 Redis 的访问控制不是很强。此外,如果会话数据存储在 Web 服务器上,则服务器上的任何管理员几乎都可以无限制地访问任何已登录用户的会话,这可能是也可能不是问题,具体取决于您的情况。

缓存失效问题

如果您只查询一次数据库并在第一次查询后将数据存储在会话中,那么您实际上是将会话用作缓存,并且存在所有相关问题。从安全角度来看,其中最重要的可能是缓存失效。想象一下,您在登录时存储用户对会话的访问权限,这样您就不必再查询它们了。如果用户登录并保持他的会话很长一段时间(只要你的绝对会话超时允许,如果有的话),但他的访问权限同时发生变化,最重要的是,如果权限被撤销怎么办?除非您设计逻辑使缓存无效,否则会话中的缓存将无效,这对于某些会话存储可能非常困难,而对于更简单的存储仍然很复杂。减轻这种风险的一种方法是实施强制注销,

会话相关的应用程序漏洞

想到的另一个威胁是,由于源代码中的安全漏洞,您的应用程序可能允许用户在一定程度上编辑会话内容。如果您将整个对象存储在会话中并且不再查询数据库,则此类漏洞可能允许攻击者提升他的权限并获得对他不应该访问的内容的访问权限。显然,这种允许编辑会话内容的漏洞的可能性可能不是很高,如果存在这样的漏洞,如果它在每次请求时都转向数据库,也会影响您的应用程序。但是,在后一种情况下,这种攻击的影响可能会更小。

结论

It is not inherently insecure to store your user objects in the session. You can do that if you mitigate or accept the risks. However, you should know about the issues detailed above and decide for yourself whether they are genuine risks for your application and whether you can mitigate or want to accept them.

于 2016-10-20T22:11:07.353 回答