【実務・中級編】 Azure AD (Entra ID) における条件付きアクセスと多要素認証(MFA)の強制 – 暗号理論・認証基盤 & エンドポイントセキュリティ防御ガイド

認証の「壁」を再定義せよ:Entra IDと条件付きアクセスで構築するゼロトラストの最前線

現場でインシデント対応をしていると痛感する。多くのシステムが「パスワード」という、もはや賞味期限切れの認証方式に依存して崩壊している現実を。

今日は、教科書的な説明は飛ばす。RSAやECCの数理的背景も大切だが、実戦においては「どうやって認証プロセスをハックさせないか」という設計思想こそが命だ。今回は、Azure AD (Entra ID) を中心とした現代的な防御策、条件付きアクセス(Conditional Access)によるゼロトラストの実装について、泥臭い知見を共有する。

—

1. なぜ「認証」は突破されるのか:PoCの視点から見る脆弱性

攻撃者は、あなたのシステムが「どこからアクセスされても、正しいパスワードさえあれば通す」という甘い設定になっていることを知っている。

彼らが狙うのは、「レガシー認証」だ。SMTP、POP、IMAPなどの古いプロトコルはMFAをサポートしないことが多い。これを利用したパスワードスプレー攻撃や、セッションCookieを直接盗み出すAiTM(Adversary-in-the-Middle)攻撃が現在の主流だ。

特に、中間者攻撃ツール(Evilginx2など)を使えば、MFAのワンタイムコードさえもバイパスしてセッションを奪取される。だからこそ、「パスワードさえあれば良い」という設計自体を、今すぐ捨てなければならない。

—

2. 条件付きアクセス:防御の「門番」を実装する

ゼロトラストの本質は「境界の内側=安全」という幻想を捨てることだ。Entra IDの条件付きアクセス(CA)は、以下の3つの要素をリアルタイムで評価する。

1. 誰が(ユーザー・グループ)
2. どこから(場所・リスク・デバイス)
3. 何に(アプリケーション)

これらを組み合わせ、「リスクが高いならMFAどころかアクセス自体を遮断する」というポリシーを定義する。

実践:レガシー認証を完全に叩き潰す設定

管理ポータルで設定するのはもちろん、Infrastructure as Code (IaC) で管理するのがプロの流儀だ。以下は、レガシー認証を禁止し、管理アカウントに対してのみ強固なMFAを強制する条件付きアクセス・ポリシーの概念的なJSON定義(Graph API形式)だ。

{
  "displayName": "Block Legacy Auth and Force MFA",
  "state": "enabled",
  "conditions": {
    "clientAppTypes": [
      "exchangeActiveSync",
      "other" 
    ],
    "users": {
      "includeUsers": ["All"]
    },
    "applications": {
      "includeApplications": ["All"]
    }
  },
  "grantControls": {
    "operator": "OR",
    "builtInControls": [
      "mfa"
    ],
    "authenticationStrength": {
      "id": "【ここに認証強度のIDを指定】"
    }
  }
}

—

3. アプリ開発者が行うべき「暗号学的防御」の勘所

Webアプリ側で認証トークン(JWT)を扱う際、RSAや楕円曲線暗号(ECC)の知識は必須だ。だが、「暗号化されているから安全」という思い込みが一番危ない。

特に、JWTの alg: "none" 脆弱性や、公開鍵の取り違え攻撃には注意が必要だ。PythonでJWTを検証する際は、ライブラリ任せにせず、必ず発行者(iss)とオーディエンス(aud)を厳密に検証すること。

import jwt

# 認証トークンの検証サンプル
def verify_token(token, public_key):
    try:
        # RS256(RSA署名)を強制し、noneアルゴリズムを拒否する
        payload = jwt.decode(
            token, 
            public_key, 
            algorithms=["RS256"], 
            audience="your-app-id",
            issuer="https://sts.windows.net/your-tenant-id/"
        )
        return payload
    except jwt.InvalidTokenError as e:
        # ここでログに「誰が」不正なトークンを投げたか記録し、アラートを飛ばす
        print(f"セキュリティアラート: 不正なトークンが検出されました: {e}")
        return None

—

4. 現場の教訓:完璧な防御は「運用」にある

技術的な設定を完璧にしても、運用がズボラなら意味がない。以下の3点は、明日から即座にチェックリストに入れてほしい。

  • 特権IDの常時利用をやめる: 普段は一般ユーザー権限でログインし、必要な時だけPIM(Privileged Identity Management)で昇格する。
  • 「場所」による制限を疑え: IP制限は便利だが、VPN経由の攻撃には無力だ。必ず「デバイスのコンプライアンス状態(Intune等による管理下にあるか)」を条件に含めること。
  • サインインログの異常検知: 「Impossible Travel(あり得ない移動距離)」のアラートが飛んだら、それは既に侵入されている合図だ。迷わずアカウントを無効化し、セッションを強制終了させろ。

最後に

セキュリティは「パッチを当てて終わり」の作業ではない。攻撃者の技術が進化するように、我々の設計思想も常にアップデートしなければならない。

「面倒くさい」と感じたその瞬間が、攻撃者にとっての最大のチャンスだ。コードを一行書く時、設定を一つ反映する時、常に「これが突破されたらどうなるか?」を自問自答してほしい。その疑い深さこそが、最強のセキュリティツールだ。

もし設定の細部で迷うことがあれば、またいつでも聞いてくれ。現場の最前線で、共に戦おう。

コメント

タイトルとURLをコピーしました