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

T.J*_*der 15 .net c# security

合理的,从安全的被黑客攻击这样的情况下,我从得到的或具有对给我的装配虚假的身份信息?当然,没有什么是完全防篡改的,但鉴于微软对.Net的承诺和依赖,我认为像这样的关键API会被锁定并难以篡改.这是我的有效假设吗?System.Security.Principal.WindowsIdentity Thread.CurrentPrincipalIdentityWindowsIdentity.GetCurrent()trueIsAuthenticated

我的目标是在我的程序集中提供合理的最佳实践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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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


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

  • 这个答案提出了主张

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

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

  • 我可以找到大量的人们愉快地使用WindowsIdentity他们的代码中的信息的例子,但他们中的大多数人并没有问他们是否安全的问题.有一个含义,但......

Dam*_*ver 10

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

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

var admin = new WindowsIdentity(@"Administrator");
var princ = new WindowsPrincipal(admin);
System.Threading.Thread.CurrentPrincipal = princ;
Run Code Online (Sandbox Code Playgroud)

...在调用代码之前.在我的机器上,创建的WindowsIdentity对象具有IsAuthenticatedas trueIsAnonymousfalse,因此,当然,您的代码会提取我的域管理员的SID.

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

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);
Run Code Online (Sandbox Code Playgroud)

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


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