ゼロトラストの「お守り」はなぜ突破されるのか?デバイスポスチャチェックの真実
現場でインシデント対応をしていると、よくこんな相談を受ける。「ゼロトラストを導入したから、VPNもやめて社内システムをSaaS化して万全です」と。
だが、現実は甘くない。攻撃者は、正当な権限を持つユーザーの「盗まれたセッション」や「管理外のデバイス」を狙い撃ちにする。ゼロトラストにおけるデバイスポスチャチェック(Device Posture Check)は、単なる「おまじない」ではない。接続のたびに「お前は本当に信頼できるデバイスか?」と問い続け、疑わしければ即座に遮断する、いわば門番の肝だ。
今日は、このポスチャチェックを突破しようとする攻撃者の視点と、それを防ぐための実戦的な実装について話をしよう。
1. 攻撃者はどこを突くのか?(PoC的視点)
攻撃者が狙うのは、ポスチャチェックの「判定プロセスの脆弱性」だ。
よくあるのが、「クライアントサイドでの判定」を過信しているケース。例えば、ブラウザから送られてくる「OSバージョン」や「アンチウイルス稼働状況」を、JavaScriptだけで判定してサーバー側に送っているような設計だ。
攻撃者は、ブラウザのデベロッパーツールを開き、APIリクエストを改ざんする。ポスチャチェックのAPIに対し、is_antivirus_enabled: true といった偽のJSONを送り込めば、サーバー側のチェックはあっさりパスする。これが「ガバナンス」の皮を被った「ザル」の正体だ。
2. サーバーサイドで完結する「ポスチャ検証」の実装
ポスチャチェックは、必ず「サーバー側」で検証し、かつ「証明書」や「ハードウェアID」と紐付ける必要がある。
ここでは、AWS環境を想定した簡単なPython(FastAPI)での実装例を紹介する。クライアントデバイスから送られてくる「信頼されたデバイス証明書」のフィンガープリントと、管理用DBの情報を突合するロジックだ。
from fastapi import FastAPI, Header, HTTPException
import ssl
app = FastAPI()
# 本来はDBやAWS IoT Core、またはMDM(Intune等)のAPIと連携させる
def verify_device_posture(cert_serial: str):
"""
デバイス証明書のシリアル番号を検証し、
そのデバイスがMDMで『準拠』状態かを確認するロジック
"""
# 実際の実務ではここでMDMのAPIを叩く
trusted_serials = ["A1B2C3D4E5", "F6G7H8I9J0"]
return cert_serial in trusted_serials
@app.get("/secure-resource")
async def get_resource(x_device_cert_serial: str = Header(None)):
# クライアントから渡された証明書シリアルを検証
if not x_device_cert_serial or not verify_device_posture(x_device_cert_serial):
raise HTTPException(
status_code=403,
detail="デバイスがポスチャ要件を満たしていません。MDMを確認してください。"
)
return {"message": "認証されたデバイスですね。機密データへアクセスを許可します。"}
このコードの肝は、x_device_cert_serial をクライアントの「自己申告」ではなく、Nginx等のリバースプロキシで「クライアント証明書認証(mTLS)」を行った結果から抽出した値として受け取ることにある。
3. インフラ側(Nginx)での防御設定
アプリケーションの手前で、mTLSを使ってデバイス自体を認証するのが鉄則だ。以下は、証明書を持たないデバイスを入り口で遮断するためのNginx設定例である。
server {
listen 443 ssl;
server_name secure.example.com;
# クライアント証明書を必須にする設定
ssl_verify_client on;
# 信頼するCA証明書(自社のMDMから発行されたもの)
ssl_client_certificate /etc/nginx/certs/ca.crt;
location / {
# 証明書からシリアル番号を抽出し、バックエンドに渡す
proxy_set_header X-Device-Cert-Serial $ssl_client_serial;
# ここでバックエンド(Python/PHP等)へリクエストを転送
proxy_pass http://internal_api;
}
}
4. 最後に:泥臭い運用こそが最強のセキュリティ
どんなに完璧なコードを書いても、社員が「PCのパスワードを付箋に書いて貼っている」とか「MDMの監視を無効化するスクリプトを走らせている」という状況では、技術的な防御は無意味になる。
私の経験上、最も堅牢なのは以下の3段構えだ。
1. 物理デバイスの資産管理: MDM(Microsoft IntuneやJamf)で制御し、ポスチャ要件を満たさない端末は強制的に社内リソースへのアクセスを遮断する。
2. mTLSの強制: 証明書がない端末は、そもそもサーバーに到達させない。
3. 継続的なアノマリ検知: 「普段は東京からアクセスするユーザーが、深夜に海外からアクセスしている」といった振る舞いを、SIEM等で監視する。
技術はあくまで手段に過ぎない。君たちが書くコードは、この「守りの層」の一番内側、最後の砦だ。だからこそ、表面的な実装ではなく、「どこから攻撃者が入ってくるか」を常に想像しながら設計してほしい。
もし実装で迷ったら、いつでも相談してくれ。セキュリティは、教科書を読むことよりも、こうして現場の泥臭い戦い方を議論することから始まるのだから。
コメント