System.Security.Principal.WindowsIdentity的使用是否合理安全?

System.Security.Principal.WindowsIdentity是否合理安全,不会被黑客攻击,这样我从Thread.CurrentPrincipalIdentityWindowsIdentity.GetCurrent()得到的实例对于IsAuthenticatedtrue ,会给我的程序集提供虚假身份信息? 当然,没有什么是完全防篡改的,但鉴于微软对.Net的承诺和依赖,我认为像这样的关键API会被锁定并难以篡改。 这是我的有效假设吗?

我的目标是在我的程序集中提供合理的最佳实践SSO。 如果Windows本身受到了损害,那是我无法控制的,但是如果(例如)对于链接到我的程序集的应用程序而言,这是一个直接的问题,以便向我提供虚假信息,那就是因为我没有做尽职调查。 这对我来说是一个无知的大区域。

要清楚,我正在寻找难以获得的信息,而不是袖手旁观。 因此,发布的漏洞利用,或者以一种欺骗我的代码等方式展示WindowsIdentity构造函数的使用。或者在“那是一个有效的假设”方面,支持它的固体文章,依赖它的已知用途等等。找到它们有很多运气,但我已经将我在目前为止在分频器下发现的内容包括在内。

以下是我打算如何使用WindowsIdentity

 using System.Security.Principal; using System.Threading; // ... // I only want Windows-authenticated users WindowsIdentity identity = Thread.CurrentPrincipal == null ? null : Thread.CurrentPrincipal.Identity as WindowsIdentity; SecurityIdentifier sid; // I can't imagine how an authenticated account would be anonymous, but... if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) { // SSO success from thread identity sid = identity.User; // ...check that that SID is allowed to use our system... } else { identity = WindowsIdentity.GetCurrent(); if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) { // SSO success from current Windows user sid = identity.User; // ...check that that SID is allowed to use our system... } else { // SSO fail } } 

这是一个DLL程序集 – 遗憾的是我们被困在.Net 3.5上 – 为可能受用户权限限制的资源提供公共API。 它可能在桌面应用程序中使用,或者在使用Windows身份validation的ASP.Net IIS应用程序中使用(ASP.Net在使用Windows身份validation时在Thread.CurrentPrincipal.Identity上设置WindowsIdentity实例;我们目前不支持其他类型的IIS身份validation) 。

我是否可以合理地信任来自WindowsIdentity实例的SID来自那些声称要经过身份validation的来源?

我不想知道这是否合适( doh! )直到在这个问题用户lc中。 引起了人们的担忧,即集会很容易受到与之相关的恶意应用程序的欺骗,并“伪造”了这些信息。 他没有任何具体的证据来指出为什么这可能是一个重要的问题,因此这个问题。


到目前为止我发现了什么(小):

  • 这个答案提出了主张

    您可以相信当前的WindowsIdentity就是它所说的那样,只要您可以信任应用程序中的任何给定数据。

  • 黑客守则 ”一书声称ASP.Net要求在进行文件授权检查时将WindowsIdentity与请求相关联,如果真的看起来像是一个相当坚实的基础,说微软,至少认为它足够好。

  • 我可以找到很多人在他们的代码中愉快地使用WindowsIdentity信息的例子,但他们中的大多数人都不会问他们是否安全。 有一个含义 ,但……

你不能相信Thread.CurrentPrincipal那个,不。 没有什么可以阻止代码通过欺骗来完全信任。

我能够在我的环境中欺骗它,如下所示:

 var admin = new WindowsIdentity(@"Administrator"); var princ = new WindowsPrincipal(admin); System.Threading.Thread.CurrentPrincipal = princ; 

…在调用代码之前。 在我的机器上,创建的WindowsIdentity对象的IsAuthenticatedtrueIsAnonymous false,因此,当然,您的代码会提取我的域管理员的SID。

这在所有环境中都不起作用,但如果正在运行的代码具有足够的权限来使用reflection,则应该这样做:

 var ident = WindowsIdentity.GetCurrent(); Thread.CurrentPrincipal = new WindowsPrincipal(ident); var userSid = ident.User; var fakeSid = new SecurityIdentifier("S-1-3-0"); typeof (WindowsIdentity).GetField("m_user", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ident, fakeSid); 

(再次,在调用代码之前完成。)


基本上,没有什么可以阻止在同一个进程中在完全信任下运行的两段代码互相说谎。