title: Is this use of System.Security.Principal.WindowsIdentity reasonably secure?
body: <p>Is <a href="https://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity(v=vs.90).aspx" rel="noreferrer"><code>System.Security.Principal.WindowsIdentity</code></a> <em>reasonably</em> secure from being hacked such that an instance I get from <a href="https://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal(v=vs.110).aspx" rel="noreferrer"><code>Thread.CurrentPrincipal</code></a>'s <code>Identity</code> or <a href="https://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.getcurrent(v=vs.90).aspx" rel="noreferrer"><code>WindowsIdentity.GetCurrent()</code></a> which has <code>true</code> for <code>IsAuthenticated</code> 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 <em>Locked Down Hard</em> and difficult to tamper with. Is that a valid assumption on my part?</p>
  <p>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.</p>
  <p>To be clear, I'm looking for hard information, not off-the cuff opinions. So, published exploits, or demonstrated use of a <code>WindowsIdentity</code> constructor in a way that would trick my code, etc. Or on the &quot;that's a valid assumption&quot; 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.</p>
  <p>Here's how I intend to use <code>WindowsIdentity</code>:</p>
  <pre><code>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 &amp;&amp; identity.IsAuthenticated &amp;&amp; !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 &amp;&amp; identity.IsAuthenticated &amp;&amp; !identity.IsAnonymous) {
          // SSO success from current Windows user
          sid = identity.User;
          // ...check that that SID is allowed to use our system...
      } else {
          // SSO fail
      }
  }
  </code></pre>
  <p>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 <code>WindowsIdentity</code> instance on <code>Thread.CurrentPrincipal.Identity</code> when using Windows auth; we don't support other kinds of IIS auth presently).</p>
  <p>Can I reasonably trust a SID from a <code>WindowsIdentity</code> instance from those sources claiming to be authenticated like that?</p>
  <p>It didn't occur to me to wonder if that was okay (<em>doh!</em>) until in <a href="https://stackoverflow.com/questions/33551014/get-windows-or-iis-user-without-access-to-page">this question</a> user <a href="https://stackoverflow.com/users/44853/lc">lc.</a> raised a concern that the assembly would be susceptible to being tricked by a malicious app that linked with it and &quot;faked&quot; that information. He didn't have any specific evidence to point to for why that might be a significant concern, though, hence this question.</p>
  <hr />
  <p>What (little) I've found so far:</p>
  <ul>
  <li><p><a href="https://stackoverflow.com/a/3501746/157247">This answer</a> makes the claim</p>
  <blockquote>
  <p>You can trust that the current <code>WindowsIdentity</code> is who it says it is, insofar as you can trust any given piece of data in your application.</p>
  </blockquote>
  </li>
  <li><p>The book <a href="https://books.google.co.uk/books?id=-WShG0uezvEC" rel="noreferrer"><em>Hacking the Code</em></a> claims that ASP.Net requires a <code>WindowsIdentity</code> 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.</p>
  </li>
  <li><p>I can find plenty of examples of people happily using the <code>WindowsIdentity</code> information in their code, but most of them don't ask the question of whether they're secure. There's an <em>implication</em>, but...</p>
  </li>
  </ul>