はじめに
こんにちは、Claude Codeを使っていますか?
私の観測範囲内でもClaude Codeを使っている人がどんどん増えてきています。
他のAIコーディングエージェントから乗り換えている人も結構な人数いそうです。
今回の記事ではClaude Codeに脆弱性の診断をさせてみました。
診断の対象としたのは以前の記事でClaude Codeに作ってもらった以下のAIチャットボットのアプリケーションです。
リポジトリはこちら
記事はこちら
実践
診断開始
今回はClaude Codeで以下のようなプロンプトで指示を出しました。
> あなたは経験豊富なセキュリティ専門家(ホワイトハッカー)として行動してください。
**要求する分析内容:**
1. **脆弱性の特定**
- 発見した脆弱性の種類と場所を明確に指摘
- 各脆弱性のCVE分類またはOWASP Top 10での位置づけ
2. **リスク評価**
- 各脆弱性の深刻度(Critical/High/Medium/Low)
- 悪用された場合の潜在的影響
3. **具体的な対策案**
- 各脆弱性に対する修正コード例
- 実装時のベストプラクティス
- 予防策や追加のセキュリティ対策
**出力形式:**
脆弱性ごとに以下の構造で回答してください:
- 脆弱性名
- 問題の詳細説明
- 影響度とリスク
- 修正方法(コード例含む)
実際に発見した脆弱性はこちら
1. immediate action required: SQLインジェクション脆弱性の修正を最優先で実施
2. Dependencies: 以下のセキュリティライブラリの追加を推奨
uv add bleach python-magic
3. Security Headers: Streamlitアプリに適切なセキュリティヘッダーを設定
4. Input Validation: 全ユーザー入力に対する包括的な検証機能の実装
5. Logging Security: 機密情報がログに含まれないよう、ログ出力の見直し
6. Regular Security Audits: 定期的なセキュリティ監査の実施
緊急度: SQLインジェクション(High)> ファイルアップロード検証(Medium)> XSS対策(Medium)> 情報漏洩対策(Medium)> セッション管理(Low)
Claude Code Output全文
⏺ セキュリティ脆弱性分析レポート
---
🔴 1. SQLインジェクション脆弱性
場所: src/utils/database.py:249脆弱性名: SQL Injection (OWASP Top 10
問題の詳細:
検索機能でLIKE句に直接ユーザー入力を結合している箇所でSQLインジェクション脆弱性が発生しています。
cursor.execute('''
WHERE m.content LIKE ?
''', (f'%{query}%', limit))
影響度とリスク:
- データベース内の全会話履歴の漏洩
- 悪意のあるSQLコマンドの実行による任意データの削除・改変
- システム権限の昇格(SQLiteの制限により限定的)
修正方法:
def search_messages(self, query: str, limit: int = 50) -> List[Dict[str, Any]]:
sanitized_query = query.replace("'", "''").replace("%", "\\%").replace("_", "\\_")
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute('''
SELECT c.session_id, c.title, c.model_name, m.role, m.content, m.timestamp
FROM messages m
JOIN conversations c ON m.conversation_id = c.id
WHERE m.content LIKE ? ESCAPE '\\'
ORDER BY m.timestamp DESC
LIMIT ?
''', (f'%{sanitized_query}%', limit))
---
🟡 2. ファイルアップロード時の検証不備
場所: src/app.py:85-90, src/utils/file_processing.py:156-176脆弱性名: Unrestricted File Upload (OWASP Top 10
問題の詳細:
ファイル拡張子のみでの検証で、実際のファイル内容(マジックバイト)の検証が不十分です。
影響度とリスク:
- 悪意のあるファイルのアップロード
- ファイル偽装による不正なスクリプト実行のリスク
修正方法:
import magic
def validate_file_content(uploaded_file) -> bool:
"""ファイル内容の検証"""
uploaded_file.seek(0)
file_content = uploaded_file.read(2048)
uploaded_file.seek(0)
mime_type = magic.from_buffer(file_content, mime=True)
allowed_mime_types = {
'image/png', 'image/jpeg', 'image/gif',
'image/bmp', 'image/webp', 'application/pdf'
}
return mime_type in allowed_mime_types
---
🟡 3. XSS (Cross-Site Scripting) 潜在的脆弱性
場所: src/app.py:236, src/app.py:300脆弱性名: Stored XSS (OWASP Top 10
問題の詳細:
ユーザー入力をそのままMarkdownとして表示しており、HTMLタグやJavaScriptの実行可能性があります。
修正方法:
import html
import bleach
def sanitize_user_input(content: str) -> str:
"""ユーザー入力のサニタイゼーション"""
escaped_content = html.escape(content)
allowed_tags = ['b', 'i', 'u', 'em', 'strong', 'code', 'pre']
clean_content = bleach.clean(escaped_content, tags=allowed_tags)
return clean_content
sanitized_content = sanitize_user_input(user_message_content)
st.markdown(sanitized_content)
---
🟡 4. 機密情報のログ出力
場所: src/models/factory.py:66, src/utils/history_manager.py:40脆弱性名: Information Disclosure深刻度: Medium
問題の詳細:
API キーやセッション情報がログに出力される可能性があります。
修正方法:
def create_model(model_name: str, **kwargs) -> Optional[BaseChatModel]:
logger.info(f"モデル作成開始: {model_name}")
config = ModelConfig.MODELS[model_name]
api_key = os.getenv(config["api_key_env"])
if not api_key:
logger.warning(f"APIキーが設定されていません: {config['api_key_env']}")
return None
logger.debug(f"APIキー確認済み: {config['api_key_env'][:10]}...")
---
🟢 5. セッション管理の改善
場所: src/utils/history_manager.py:38-41脆弱性名: Session Management深刻度: Low
修正方法:
import secrets
def start_new_session(self, model_name: str = None) -> str:
"""暗号学的に安全なセッションID生成"""
session_id = secrets.token_urlsafe(32)
self._current_session_id = session_id
logger.info(f"新しいセッション開始: {session_id[:8]}..., model: {model_name}")
return session_id
---
📋 総合推奨事項
⏺ Update Todos
⎿ ☒ Analyze the codebase for security vulnerabilities
☒ Identify specific vulnerability types and locations
☒ Assess risk levels for each vulnerability
☒ Provide specific remediation code examples
⏺ 1. immediate action required: SQLインジェクション脆弱性の修正を最優先で実施
2. Dependencies: 以下のセキュリティライブラリの追加を推奨
uv add bleach python-magic
3. Security Headers: Streamlitアプリに適切なセキュリティヘッダーを設定
4. Input Validation: 全ユーザー入力に対する包括的な検証機能の実装
5. Logging Security: 機密情報がログに含まれないよう、ログ出力の見直し
6. Regular Security Audits: 定期的なセキュリティ監査の実施
緊急度: SQLインジェクション(High)> ファイルアップロード検証(Medium)> XSS対策(Medium)> 情報漏洩対策(Medium)> セッション管理(Low)
タスク化
発見した脆弱性についてはissue化しました。
もちろんClaude Codeにやってもらいました。
発見された脆弱性をissue化してくださいと指示を出すだけです。
⏺ ✅ セキュリティ脆弱性のGitHubイシュー化が完了しました
作成されたイシュー:
1. 🔴 [CRITICAL] SQL Injection vulnerability - Issue
- 最優先対応が必要な重大な脆弱性
2. 🟡 [Security] Improve file upload validation - Issue
- ファイルアップロード時の検証強化
3. 🟡 [Security] Prevent XSS in user content display - Issue
- XSS攻撃の防止
4. 🟡 [Security] Prevent sensitive information logging - Issue
- 機密情報のログ出力防止
5. 🟢 [Security] Improve session ID generation - Issue
- セッションID生成の強化
各イシューには詳細な脆弱性情報、影響度、修正方法が記載されています。特にイシュー
修正
当然、発見された脆弱性の修正もClaude Codeに実施してもらいます。
今回は緊急度の高いSQLインジェクションの対応を実施しました。
先日導入されたplan modeを使い修正の方針を考えてもらいます。
Claude Code Output全文(plan mode)
⏺ 現在のSQLインジェクション脆弱性を分析し、修正方針を検討します。
現在の問題点
脆弱箇所: src/utils/database.py:252
cursor.execute('''
WHERE m.content LIKE ?
''', (f'%{query}%', limit))
問題: f'%{query}%'でユーザー入力を直接文字列結合しており、SQLインジェクション攻撃が可能
修正方針
1. 適切なプレースホルダー使用
現在のコードは一見プレースホルダー(?)を使用しているように見えますが、f'%{query}%'の部分で実際には文字列結合を行っています。
2. LIKE句特殊文字のエスケープ
LIKE句では%、_、\が特殊な意味を持つため、これらをエスケープする必要があります。
3. 入力検証の強化
- 空文字・None チェック
- データ型検証
- 長さ制限
4. SQLiteのESCAPE句使用
エスケープ文字を明示的に指定してクエリの安全性を確保
修正案
def search_messages(self, query: str, limit: int = 50) -> List[Dict[str, Any]]:
"""
メッセージを検索(SQLインジェクション対策済み)
"""
if not query or not isinstance(query, str):
return []
if len(query) > 1000:
query = query[:1000]
escaped_query = query.replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_')
search_pattern = f'%{escaped_query}%'
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute('''
SELECT c.session_id, c.title, c.model_name, m.role, m.content, m.timestamp
FROM messages m
JOIN conversations c ON m.conversation_id = c.id
WHERE m.content LIKE ? ESCAPE '\\'
ORDER BY m.timestamp DESC
LIMIT ?
''', (search_pattern, limit))
テスト計画
修正後に以下のテストケースで検証:
1. 正常系テスト
- 通常の検索クエリ
- 日本語文字列
- 特殊文字を含む正当な検索
2. SQLインジェクション攻撃テスト
- '; DROP TABLE messages; --
- %'; INSERT INTO messages...; --
- ' UNION SELECT * FROM conversations --
3. LIKE句特殊文字テスト
- %、_を含む検索
- エスケープが正しく動作するか確認
修正案やテスト計画などの内容を確認し問題なければ実際に修正を実施してもらいます。
⏺ ✅ SQLインジェクション脆弱性の修正が完了しました
修正内容
1. コード修正: src/utils/database.pyのsearch_messages()メソッド
- 入力検証を追加(空文字・型・長さチェック)
- LIKE句特殊文字のエスケープ(%、_、\)
- ESCAPE句をSQLクエリに追加
- プレースホルダーの適切な使用
2. セキュリティテストの追加: tests/test_history_database.py
- 新しいテストメソッドtest_search_messages_sql_injection_protection()を追加
- SQLインジェクション攻撃パターンをテスト:
- '; DROP TABLE messages; --
- ' OR '1'='1
- '; DELETE FROM conversations; --
- ' UNION SELECT session_id FROM conversations --
- %'; INSERT INTO messages (content) VALUES ('hacked'); --
3. テスト結果
- ✅ 81個のテスト全てが成功
- ✅ SQLインジェクション攻撃が防止されることを確認
- ✅ 既存機能に回帰がないことを確認
- ✅ LIKE句の特殊文字が正しくエスケープされることを確認
修正前後の比較
修正前(脆弱):
cursor.execute('''WHERE m.content LIKE ?''', (f'%{query}%', limit))
修正後(安全):
escaped_query = query.replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_')
search_pattern = f'%{escaped_query}%'
cursor.execute('''WHERE m.content LIKE ? ESCAPE '\\\'''', (search_pattern, limit))
Issue
実際に修正したコードはこちらのPRで確認できます。
まとめ
今回はClaude Codeを使って脆弱性診断を実施し、発見された問題の修正まで完了できました。
ただし、今回対象としたアプリケーションは比較的シンプルな構成であり、マイクロサービスアーキテクチャや膨大なプログラムが稼働しているシステムでの診断精度については別途検証が必要です。また、ビジネスロジック固有の脆弱性や組織特有のセキュリティ要件については、生成AIだけに頼るのではなく人間による診断が不可欠だと考えています。
Claude Codeは脆弱性の発見から修正、テストまでの一連の流れを効率化してくれますが、最終的な判断は人間が行うことが重要です。
セキュリティは継続的な取り組みが必要かと思います。その継続的な取り組みの中にセキュリティチェックの一部としてClaude Codeを組み込むことでより簡単に安全なアプリケーションを構築できるのではないかと思いました。
Views: 0