{
"event": "PostToolUse",
"raw_data": {
"session_id": "18ef5bf3-e872-4052-897e-53d6dc45b0b9",
"transcript_path": "\/root\/.claude\/projects\/-var-www\/18ef5bf3-e872-4052-897e-53d6dc45b0b9.jsonl",
"cwd": "\/opt\/scripts\/pipeline",
"permission_mode": "acceptEdits",
"hook_event_name": "PostToolUse",
"tool_name": "Read",
"tool_input": {
"file_path": "\/opt\/scripts\/hooks\/block_direct_db.py"
},
"tool_response": {
"type": "text",
"file": {
"filePath": "\/opt\/scripts\/hooks\/block_direct_db.py",
"content": "#!\/usr\/bin\/env python3\n\"\"\"\nClaude Code Hook: Blockiert direkte DB-Zugriffe\nErzwingt Nutzung von MCP-DB Server\n\nHook Type: PreToolUse\nBlockiert: Bash-Befehle mit mysql\/mariadb und Passwort-Parametern\nEmpfehlung: MCP-DB Tools verwenden (db_select, db_schema, db_stats)\n\"\"\"\nimport json\nimport re\nimport sys\n\n\nBLOCKED_PATTERNS = [\n r'mysql\\s+.*-p\\w+', # mysql mit Passwort inline\n r'mariadb\\s+.*-p\\w+', # mariadb mit Passwort inline\n r'mysql\\s+-u\\s+\\w+\\s+-p', # mysql -u user -p\n r'mariadb\\s+-u\\s+\\w+\\s+-p', # mariadb -u user -p\n r'mysql.*--password=', # mysql --password=xxx\n r'mariadb.*--password=', # mariadb --password=xxx\n]\n\nERROR_MESSAGE = \"\"\"\nBLOCKIERT: Direkte Datenbankzugriffe sind aus Sicherheitsgründen nicht erlaubt.\n\nVerwende stattdessen die MCP-DB Tools:\n - db_select(query, params) : SELECT-Abfragen ausführen\n - db_schema() : Datenbank-Schema anzeigen\n - db_stats() : Statistiken abrufen\n\nVorteile von MCP-DB:\n - Keine Credentials im Code\/Verlauf\n - Automatische Query-Validierung\n - SQL-Injection Schutz\n - Audit-Logging aller Abfragen\n - Enforced Read-Only Zugriff\n\nDokumentation: \/docs\/mcp\/mcp-db\n\"\"\".strip()\n\n\ndef check_command(command: str) -> tuple[bool, str]:\n \"\"\"\n Prüft ob Befehl blockiert werden soll.\n\n Returns:\n (allowed, error_message)\n \"\"\"\n for pattern in BLOCKED_PATTERNS:\n if re.search(pattern, command, re.IGNORECASE):\n return False, ERROR_MESSAGE\n return True, \"\"\n\n\ndef main():\n \"\"\"\n Hook Entry Point (PreToolUse).\n\n Input (stdin): JSON mit tool_name und tool_input\n Output (stdout): JSON mit allow\/deny\n Exit Code: 0 = allowed, 1 = denied\n \"\"\"\n try:\n # Lese Hook-Input von stdin\n hook_input = json.loads(sys.stdin.read())\n\n tool_name = hook_input.get(\"tool_name\", \"\")\n tool_input = hook_input.get(\"tool_input\", {})\n\n # Nur Bash-Tool prüfen\n if tool_name != \"Bash\":\n # Andere Tools durchlassen\n result = {\n \"allowed\": True,\n \"message\": \"\"\n }\n print(json.dumps(result))\n sys.exit(0)\n\n # Befehl extrahieren\n command = tool_input.get(\"command\", \"\")\n\n # Prüfen ob Befehl blockiert werden soll\n allowed, error_msg = check_command(command)\n\n result = {\n \"allowed\": allowed,\n \"message\": error_msg\n }\n\n print(json.dumps(result))\n sys.exit(0 if allowed else 1)\n\n except Exception as e:\n # Bei Fehler: Fail-Open (durchlassen)\n result = {\n \"allowed\": True,\n \"message\": f\"Hook error (fail-open): {str(e)}\"\n }\n print(json.dumps(result), file=sys.stderr)\n sys.exit(0)\n\n\nif __name__ == \"__main__\":\n main()\n",
"numLines": 107,
"startLine": 1,
"totalLines": 107
}
},
"tool_use_id": "toolu_01SmPkUUv3VSSnbNainNbWvc"
}
}