フィッシング検出の実装:キーワード+送信者分析で怪しいメールを自動ブロック

はじめに

メール監視システムを構築する際、フィッシングメールの検出は必須機能です。この記事では、キーワード分析と送信者チェックを組み合わせたフィッシング検出ロジックを紹介します。

フィッシングの特徴

典型的なフィッシングメールには以下の特徴があります:

  • 緊急性を煽る: 「アカウント停止」「今すぐ」
  • 個人情報を要求: 「パスワードを更新」「本人確認」
  • 不自然な送信者: noreply、info、support など
  • リンククリックを促す: 「こちらをクリック」

実装戦略

キーワードベースのペナルティ

件名や本文に含まれる危険キーワードにペナルティを付与します。

PHISHING_KEYWORDS = [
    'アカウント停止', '緊急', 'すぐに', 'パスワードを更新',
    '本人確認', 'クリックして', '設定を更新', 'セキュリティ警告',
    'account suspended', 'verify your identity', 'urgent action required'
]

def detect_phishing(subject, body, sender):
    phishing_score = 0

    # キーワードチェック
    text = f"{subject} {body}".lower()
    for keyword in PHISHING_KEYWORDS:
        if keyword.lower() in text:
            phishing_score += 50  # 大幅減点

    # 送信者チェック
    if is_suspicious_sender(sender):
        phishing_score += 30

    return phishing_score

送信者の怪しさ判定

送信者アドレスから自動判定します:

def is_suspicious_sender(sender):
    suspicious_patterns = [
        'noreply@', 'no-reply@', 'info@', 'support@',
        'notification@', 'alert@', 'security@'
    ]

    sender_lower = sender.lower()

    # 既知の危険パターン
    for pattern in suspicious_patterns:
        if pattern in sender_lower:
            return True

    # ドメインチェック(既知の安全ドメインは除外)
    trusted_domains = ['google.com', 'github.com', 'stripe.com']
    for domain in trusted_domains:
        if domain in sender_lower:
            return False

    return False

スコア統合

フィッシングスコアを重要度スコアから減算します:

def calculate_final_score(email_data):
    importance = calculate_importance_score(email_data)
    phishing = detect_phishing(
        email_data['subject'],
        email_data['body'],
        email_data['from']
    )

    final_score = importance - phishing

    # フィッシング判定
    if phishing >= 50:
        return ('PHISHING', final_score)
    elif final_score >= 60:
        return ('HIGH', final_score)
    elif final_score >= 35:
        return ('MEDIUM', final_score)
    else:
        return ('LOW', final_score)

実運用での検出例

初回テストで以下のフィッシングメールを検出:

  • 件名: 「【緊急】アカウント停止の可能性があります」
  • 送信者: noreply@suspicious-domain.com
  • スコア: -50点(キーワード-50、送信者-30)

誤検知対策

ホワイトリスト

既知の安全な送信者をホワイトリスト化し、フィッシング判定をスキップします。

WHITELIST = [
    'support@slack.com',
    'notifications@github.com',
    'noreply@google.com'
]

def is_whitelisted(sender):
    return any(trusted in sender.lower() for trusted in WHITELIST)

学習機能(将来実装)

ユーザーのフィードバック(「これはフィッシングではない」)を記録し、ルールを改善します。

まとめ

キーワード+送信者分析のシンプルな手法でも、実用的なフィッシング検出が可能です。次のステップとしてLLM判定を組み込み、より高度な文脈理解を目指します。

関連記事:
– Gmail重要メール監視システム構築
– 複数Googleアカウント統合管理
– SQLiteでメール重複防止