コンテンツにスキップ

セキュリティログプラグイン (Security Log Plugin)

概要

顧客のログイン試行を詳細に記録し、不正アクセスの検知やカスタマーサポートの迅速化を実現するプラグイン。AES-256-GCM による認証付き暗号化、IPベースの位置情報特定、およびログイン失敗時の管理者即時通知機能を提供します。

パッケージ情報

  • パッケージ名: @ritsubi/plugins-security-log
  • パス: /packages/plugins/security-log
  • エントリーポイント: src/index.ts

実装機能

1. ログイン試行の自動記録

Shop API の login ミューテーションを LoginLogInterceptor が自動的にキャプチャし、以下の情報を LoginLog エンティティとしてデータベースに保存します。

項目 説明 備考
identifier 試行されたメールアドレス
encryptedPassword 入力されたパスワード AES-256-GCMで暗号化
ipAddress クライアントのIPアドレス
location 概算の位置情報 geoip-lite による解析結果(JSON)
success ログイン成否
failureReason 失敗理由 エラーコード(例: INVALID_CREDENTIALS_ERROR
createdAt 試行時刻 日本標準時 (JST) で表示可能

2. パスワードの安全な保存と復号

顧客が「パスワードが合っているはずなのにログインできない」と問い合わせた際、管理者が実際に入力された内容を確認できるように、可逆暗号化を採用しています。

  • 暗号化方式: AES-256-GCM (Authenticated Encryption)
  • 鍵管理: 環境変数 SECURITY_LOG_ENCRYPTION_KEY を使用。
  • 改ざん検知: GCMモードにより、保存データの改ざんを検知可能。
  • 復号表示: 特定の権限を持つ管理者のみ、管理画面 API を通じて平文パスワード(decryptedPassword)を確認できます。

3. 管理者向けメール通知

ログイン失敗が発生した際、管理者に即座にアラートメールを送信します。

  • トリガー: ログイン失敗(成功時は送信されません)
  • 通知内容: 試行メールアドレス、IPアドレス、推定位置、失敗理由、発生時刻。
  • テンプレート: MJML形式による日本語メールテンプレート (login-failure)。

4. 閲覧制限と権限管理

セキュリティログは機密性が高いため、アクセス権限を厳格に管理しています。

  • 専用権限: ReadSecurityLog
  • 閲覧可能者: SuperAdmin または上記権限を明示的に付与された「ロール」を持つ管理者のみ。
  • スタッフへの制限: 通常のCSスタッフ用ロールにはこの権限を付与しないことで、ログの露出を防げます。

技術仕様

プラグイン初期化

import { SecurityLogPlugin, loginFailureHandler } from '@ritsubi/plugins';

// vendure-config.ts
export const config: VendureConfig = {
  plugins: [
    SecurityLogPlugin.init({}),
    EmailPlugin.init({
      handlers: [
        // ログイン失敗通知ハンドラーの登録
        loginFailureHandler.setRecipient(
          () =>
            process.env.LOGIN_FAILURE_NOTIFY_EMAIL ||
            'alerts@ritsubi.mail-box.ne.jp',
        ),
      ],
      // ...
    }),
  ],
};

データベースモデル (LoginLog)

  • テーブル名: login_log
  • カラム: identifier, encryptedPassword, ipAddress, location, success, failureReason

設定・運用

環境変数

変数名 説明 推奨値
SECURITY_LOG_ENCRYPTION_KEY パスワード暗号化用の秘密鍵 32文字以上のランダム文字列
LOGIN_FAILURE_NOTIFY_EMAIL 失敗通知の宛先 alerts@ritsubi.mail-box.ne.jp

SECURITY_LOG_ENCRYPTION_KEY を変更すると、それ以前に保存された過去のログ(パスワード)は復号できなくなります(Decryption failed と表示されます)。

管理画面での確認

  1. [設定] > [グローバル設定] > [セキュリティ] タブにて通知先メールアドレスを確認できます。
  2. 特定のスタッフに閲覧を許可する場合、[設定] > [ロール] から ReadSecurityLog 権限をチェックしてください。

セキュリティ考慮事項

  1. 生パスワードの非保持: データベース上には暗号文のみが存在します。
  2. ブルートフォース対策: このログを活用して、短期間に同一IPから多数の失敗がある場合の監視が可能です。
  3. GDPR/プライバシー: IPアドレスと位置情報を保持するため、プライバシーポリシーへの記載を検討してください。

開発ガイド

テストの実行

cd packages/plugins/security-log
pnpm test

すべてのロジック(暗号化・復号・インターセプター・イベント発行)はユニットテストで検証済みです。