web-dev-qa-db-ja.com

このSystem.Security.Principal.WindowsIdentityの使用は、かなり安全ですか?

_System.Security.Principal.WindowsIdentity_合理的にハッキングされないように安全ですか _Thread.CurrentPrincipal_Identityまたは WindowsIdentity.GetCurrent() これはtrueIsAuthenticatedがあり、アセンブリに誤ったID情報を与えますか?もちろん、完全に改ざんされないものはありませんが、Microsoftの.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認証を使用するASP.Net IISアプリで使用される可能性があります(ASP.Netは、Windows認証を使用するときに_Thread.CurrentPrincipal.Identity_にWindowsIdentityインスタンスを設定します。他のアプリはサポートしていません。 IIS authの種類(現在)。

そのように認証されていると主張するソースからのWindowsIdentityインスタンスからのSIDを合理的に信頼できますか?

この質問 になるまで、それで大丈夫かどうか疑問に思うことはありませんでした(doh!)。ユーザー lc. は、アセンブリにリンクしてその情報を「偽造」した悪意のあるアプリにだまされやすいという懸念を表明しました。しかし、なぜそれが重大な懸念であるのかを指摘する具体的な証拠はありませんでした。したがって、この質問です。


私がこれまでに見つけたもの(少し):

  • この回答 は主張します

    アプリケーション内の特定のデータを信頼できる限り、現在のWindowsIdentityがそのとおりであると信頼できます。

  • Hacking the Code は、ASP.NetではWindowsIdentityをリ​​クエストに関連付ける必要があると主張していますファイル認証チェック。これは、trueの場合、少なくともMicrosoftと言うにはかなり堅実な根拠のように思えますが、それで十分だと考えています。

  • コード内のWindowsIdentity情報を喜んで使用している人々の例はたくさんありますが、ほとんどの人は安全かどうかについて質問していません。 含意がありますが...

15
T.J. Crowder

Thread.CurrentPrincipalからのものを信頼することはできません。完全に信頼して実行されているコードがスプーフィングするのを阻止するものは何もありません。

私はこのような私の環境でそれをスプーフィングすることができました:

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

...コードを呼び出す前。私のマシンでは、作成されたWindowsIdentityオブジェクトのIsAuthenticatedtrueおよびIsAnonymous falseであるため、もちろん、コードによってドメイン管理者の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);

(繰り返しますが、コードを呼び出す前に実行してください。)


基本的に、同じプロセス内で完全信頼の下で実行されている2つのコードが互いに嘘をつくのを防ぐことはできません。

10