Is System.Security.Principal.WindowsIdentity
reasonably secure from being hacked such that an instance I get from Thread.CurrentPrincipal
's Identity
or WindowsIdentity.GetCurrent()
which has true
for IsAuthenticated
gives my assembly false identity information? Nothing, of course, is completely tamper-proof, but given Microsoft's commitment to and reliance on .Net, I would expect critical APIs like this to be Locked Down Hard and difficult to tamper with. Is that a valid assumption on my part?
My goal here is to provide reasonable best-practices SSO in my assembly. If Windows itself is compromised, that's out of my control, but if (for instance) it's a straightforward matter for an app linking with my assembly to feed me false information, that would be on me for failing to do due diligence. This is a big area of ignorance for me.
To be clear, I'm looking for hard information, not off-the cuff opinions. So, published exploits, or demonstrated use of a WindowsIdentity
constructor in a way that would trick my code, etc. Or on the "that's a valid assumption" side, solid articles backing it up, known uses relying on it, etc. I haven't had a lot of luck finding them, but I've included what I've found so far below under the divider.
Here's how I intend to use 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
}
}
This is in a DLL assembly?— sadly we're stuck on .Net 3.5?— that provides a public API to resources that may be restricted by user rights. It might be used in desktop apps, or in an ASP.Net IIS app with Windows authentication (ASP.Net sets a WindowsIdentity
instance on Thread.CurrentPrincipal.Identity
when using Windows auth; we don't support other kinds of IIS auth presently).
Can I reasonably trust a SID from a WindowsIdentity
instance from those sources claiming to be authenticated like that?
It didn't occur to me to wonder if that was okay (doh!) until in this question user lc. raised a concern that the assembly would be susceptible to being tricked by a malicious app that linked with it and "faked" that information. He didn't have any specific evidence to point to for why that might be a significant concern, though, hence this question.
What (little) I've found so far:
This answer makes the claim
You can trust that the current WindowsIdentity
is who it says it is, insofar as you can trust any given piece of data in your application.
The book Hacking the Code claims that ASP.Net requires a WindowsIdentity
to be associated with a request when doing file authorizaton checking, which if true seems like a fairly solid basis for saying Microsoft, at least, considers it good enough.
I can find plenty of examples of people happily using the WindowsIdentity
information in their code, but most of them don't ask the question of whether they're secure. There's an implication, but...
See Question&Answers more detail:
os