存储在CallContext中的数据可能在请求之间泄漏

本文关键字:请求 泄漏 之间 数据 CallContext 存储 | 更新日期: 2023-09-27 17:57:12

在MVC应用程序中,我需要存储一些用户数据,以验证他是否拥有访问某些页面的所有权限(比如他是对象的所有者等(。我尝试在我的一个服务中添加一个私有静态字段来处理用户数据,并添加一个静态的、只获取的属性来访问私有字段。如果私有字段为null,则此属性从数据库中提取用户数据。显然,这是个坏主意,因为MVC应用程序并不是只在请求期间运行,所以一旦设置了私有静态字段,它就会无限期地停留在那里。

在搜索上述解决方案的替代方案时,我找到了ThreadStatic属性。这似乎很有效(至少乍一看(。但后来我阅读了更多关于该属性的内容,发现一个请求实际上可以由多个线程处理(在我的情况下,这不是特别的问题(,并且一些线程可以在多个请求中重用(极端但显然罕见的情况(。现在这听起来像是一个真正的问题,这意味着我曾经从数据库中提取的用户数据可能会泄露给另一个请求,并且一个用户可以根据另一个用户的数据进行验证。

所以我搜索了另一个替代方案,找到了CallContext。这一次我还注意到,人们警告说,它可能不会像人们期望的那样工作。在ThreadStatic的情况下,我们解释了使用它的风险,但在CallContext的情况下就没有那么多了。

那么,存储在CallContext中的数据是否会从一个请求泄漏到另一个请求(就像ThreadStatic字段可能发生的情况一样(,或者最糟糕的情况是在请求中间丢失数据(我可以接受(?

存储在CallContext中的数据可能在请求之间泄漏

在MVC应用程序中,我需要存储一些用户数据,以验证他是否拥有所有数据访问某些页面的权限(就像他是对象的所有者一样等等(

正如@Ron的回答所暗示的,你正在寻找的是HttpContext.Session。您需要启用会话支持。

OTOH,HttpContext.Items的生存期仅限于给定的HTTP请求,它不在请求之间流动。一些HTTP协议文本状态数据(例如cookie(将通过HttpContext.Current.Request流动。

存储在CallContext中的数据会在请求之间泄漏吗?

如果您仍然想知道逻辑调用上下文数据(CallContext.LogicalGetData/CallContext.LogicalSetData(是否在不同的HTTP请求之间流动,答案将是。如果是这样,那将是一个严重的安全漏洞,因为不同的用户可能会发出不同的请求。

然而,它确实在同一请求内的线程之间流动,因此它可以用作ThreadLocal的替代。尽管如此,还是要小心使用,因为有写时复制的行为,请查看Stephen Cleary的博客了解更多详细信息。只有当您使用异步控制器方法和async/await(或ContinueWith等(时,您可能才需要它。

根据这篇文章,你应该使用HttpContext而不是CallContext。

顺便说一句,HttpContext是"每个请求",如果你想保存数据库访问,你可以使用"会话",通过创建一个AbstractController,你可以避免控制器和操作之间的重复。

我当前的堆栈是WCF,而不是ASP.Net,但我想为标题中提出的OP问题提供一个答案:

与我在网上遇到的任何和所有资源相反,与@noseration的公认答案相反,也与原因(主要安全漏洞等(相反,我相信正确的答案,至少对于WCF来说,是:

我想小心一点,并提到我还没有完全理解其中的原因,我无法确定地再现这一点。尽管如此,由于我怀疑这可能是基于我们在公司遇到的一些偶发异常,我设置了一个实验,通过CallContext.LogicalSetData()存储OperationContext.Current.IncomingMessageHeaders.Action(在WCF中,这是操作的名称(,然后刷新一百万次,等待偶发异常的断点出现。当它最终完成时,我将存储的值与OperationContext.Current.IncomingMessageHeaders.Action进行了比较,操作(因此请求(不同。

可能是相关的:在我的WCF应用程序中读写LogicalCallContext的代码是在MessageInspector中运行的。

不幸的是,我缺乏深入的知识来创建一个稳定的工作复制示例。请随时向我询问我可能忽略的任何其他相关细节,如配置值、环境变量等,以说明我的测试用例可能是错误的。我发现自己的发现有些令人担忧,甚至不太可能,我很乐意接受纠正。在此之前,我认为与社区分享这一点是个好主意。

.Net Framework版本:4.7.2。

WCF服务托管在IIS中。


你可以在Stephen Cleary关于LogicalCallContext的博客文章中找到一些关于我观察到的其他信息(见评论部分(。