{
"event": "PreToolUse",
"tool_name": "mcp__mcp-docs__docs_update",
"tool_input": {
"id": 40,
"content": "<nav class=\"breadcrumb\">\n <a href=\"\/docs\">Dokumentation<\/a> » <a href=\"\/docs\/mcp\/mcp-db\">MCP-DB<\/a> » Sicherheit\n<\/nav>\n\n<h1>MCP-DB Sicherheit<\/h1>\n<p>Vollständige Sicherheitsmaßnahmen für 10 MCP-DB Tools.<\/p>\n\n<h2>Sicherheitsübersicht<\/h2>\n<table>\n <tr><th>Maßnahme<\/th><th>Implementierung<\/th><th>Betrifft<\/th><\/tr>\n <tr><td>Prepared Statements<\/td><td>cursor.execute(query, params)<\/td><td>Alle Tools<\/td><\/tr>\n <tr><td>Identifier-Validierung<\/td><td>Regex ^[a-zA-Z0-9_]+$<\/td><td>INSERT, UPDATE, DELETE<\/td><\/tr>\n <tr><td>Mandatory WHERE<\/td><td>where dict Pflicht<\/td><td>UPDATE, DELETE<\/td><\/tr>\n <tr><td>Default LIMIT 100<\/td><td>Automatisch bei DELETE<\/td><td>DELETE<\/td><\/tr>\n <tr><td>DDL Statement-Validierung<\/td><td>ExecuteValidator<\/td><td>db_execute<\/td><\/tr>\n <tr><td>Keyword Blocklist (15)<\/td><td>Word Boundaries<\/td><td>db_select<\/td><\/tr>\n <tr><td>Database Allowlist<\/td><td>ki_dev, ki_content<\/td><td>Alle Tools<\/td><\/tr>\n <tr><td>Query Timeout<\/td><td>30 Sekunden<\/td><td>db_select<\/td><\/tr>\n <tr><td>Row Limit<\/td><td>Max 100<\/td><td>db_select<\/td><\/tr>\n <tr><td>Query Length<\/td><td>Max 2000 Zeichen<\/td><td>db_select<\/td><\/tr>\n <tr><td>Logging<\/td><td>Jede Operation in mcp_log<\/td><td>Alle Tools<\/td><\/tr>\n <tr><td>Blocking-Hook<\/td><td>PreToolUse für Bash<\/td><td>mysql\/mariadb CLI<\/td><\/tr>\n<\/table>\n\n<h2>Schreib-Operationen Sicherheit<\/h2>\n\n<h3>db_insert<\/h3>\n<table>\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\n <tr><td>Identifier-Validierung<\/td><td>Tabellen- und Spaltennamen: <code>^[a-zA-Z0-9_]+$<\/code><\/td><\/tr>\n <tr><td>Prepared Statements<\/td><td>Werte als Parameter, nie String-Konkatenation<\/td><\/tr>\n <tr><td>DB-Whitelist<\/td><td>Nur ki_dev, ki_content erlaubt<\/td><\/tr>\n<\/table>\n\n<pre><code># Sicher: Prepared Statement\nINSERT INTO `tasks` (`title`, `status`) VALUES (%s, %s)\n# Mit values: (\"Mein Task\", \"pending\")<\/code><\/pre>\n\n<h3>db_update<\/h3>\n<div class=\"alert alert-danger\">\n<strong>UPDATE ohne WHERE ist verboten!<\/strong>\n<\/div>\n\n<table>\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\n <tr><td>Mandatory WHERE<\/td><td>Leeres where dict → status: \"denied\"<\/td><\/tr>\n <tr><td>Identifier-Validierung<\/td><td>Alle Spalten in data und where<\/td><\/tr>\n <tr><td>Prepared Statements<\/td><td>SET und WHERE Werte als Parameter<\/td><\/tr>\n<\/table>\n\n<pre><code># Erlaubt:\ndb_update(table=\"tasks\", data={\"status\": \"done\"}, where={\"id\": 42})\n\n# Blockiert (kein WHERE):\ndb_update(table=\"tasks\", data={\"status\": \"done\"}, where={})\n# → {\"status\": \"denied\", \"error\": \"WHERE clause is required...\"}<\/code><\/pre>\n\n<h3>db_delete<\/h3>\n<div class=\"alert alert-danger\">\n<strong>DELETE ohne WHERE ist verboten! Default LIMIT: 100<\/strong>\n<\/div>\n\n<table>\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\n <tr><td>Mandatory WHERE<\/td><td>Leeres where dict → status: \"denied\"<\/td><\/tr>\n <tr><td>Default LIMIT<\/td><td>Automatisch LIMIT 100 wenn nicht angegeben<\/td><\/tr>\n <tr><td>Identifier-Validierung<\/td><td>Spaltennamen in where<\/td><\/tr>\n<\/table>\n\n<pre><code># Erlaubt:\ndb_delete(table=\"mcp_log\", where={\"status\": \"error\"}, limit=50)\n\n# Blockiert (kein WHERE):\ndb_delete(table=\"mcp_log\", where={})\n# → {\"status\": \"denied\", \"error\": \"WHERE clause is required...\"}<\/code><\/pre>\n\n<h3>db_execute (DDL)<\/h3>\n<table>\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\n <tr><td>Statement-Whitelist<\/td><td>ALTER, CREATE, DROP, TRUNCATE<\/td><\/tr>\n <tr><td>ExecuteValidator<\/td><td>Prüft erstes Keyword<\/td><\/tr>\n <tr><td>Logging<\/td><td>Statement-Typ in mcp_log<\/td><\/tr>\n<\/table>\n\n<pre><code># Erlaubt:\ndb_execute(\"ALTER TABLE tasks ADD COLUMN priority INT\")\ndb_execute(\"CREATE INDEX idx_status ON tasks(status)\")\ndb_execute(\"DROP TABLE temp_data\")\ndb_execute(\"TRUNCATE TABLE cache\")\n\n# Blockiert:\ndb_execute(\"SELECT * FROM tasks\") # Kein DDL\ndb_execute(\"INSERT INTO tasks...\") # Kein DDL<\/code><\/pre>\n\n<h2>Identifier-Validierung<\/h2>\n<p>Verhindert SQL-Injection über Tabellen-\/Spaltennamen:<\/p>\n\n<pre><code>def _validate_identifier(name: str) -> bool:\n \"\"\"Validiert Tabellen-\/Spaltennamen gegen SQL-Injection.\"\"\"\n return bool(re.match(r\"^[a-zA-Z0-9_]+$\", name))<\/code><\/pre>\n\n<table>\n <tr><th>Eingabe<\/th><th>Valide<\/th><th>Grund<\/th><\/tr>\n <tr><td>tasks<\/td><td>Ja<\/td><td>Alphanumerisch<\/td><\/tr>\n <tr><td>chat_sessions<\/td><td>Ja<\/td><td>Mit Underscore<\/td><\/tr>\n <tr><td>tasks; DROP TABLE--<\/td><td>Nein<\/td><td>Sonderzeichen<\/td><\/tr>\n <tr><td>tasks`<\/td><td>Nein<\/td><td>Backtick<\/td><\/tr>\n<\/table>\n\n<h2>Blocking-Hook (PreToolUse)<\/h2>\n<p class=\"alert alert-danger\"><strong>KRITISCH:<\/strong> Direkte mysql\/mariadb-Befehle werden auf System-Ebene blockiert!<\/p>\n\n<h3>Blockierte Muster<\/h3>\n<pre><code># Blockierte Befehle (Beispiele)\nmysql -u root -pPassword123 -e \"SELECT 1\"\nmariadb -u user -pSecret\nmysql --password=geheim --execute=\"DROP TABLE users\"\nmysqldump ki_protokoll > backup.sql\nsudo mysql -u root -pPass\n\n# Stattdessen MCP-DB verwenden:\ndb_select - SELECT-Abfragen\ndb_insert - Datensätze einfügen\ndb_update - Datensätze ändern\ndb_delete - Datensätze löschen\ndb_execute - DDL (ALTER\/CREATE\/DROP)\ndb_describe - Tabellenstruktur\ndb_databases - Datenbanken auflisten\ndb_tables - Tabellen auflisten\ndb_schema - Tabellen-Metadaten\ndb_stats - MCP-Log Statistiken<\/code><\/pre>\n\n<h3>Hook-Konfiguration<\/h3>\n<p>Pfad: <code>\/var\/www\/.claude\/settings.local.json<\/code><\/p>\n\n<pre><code>{\n \"hooks\": {\n \"PreToolUse\": [\n {\n \"matcher\": \"Bash\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"\/var\/www\/tools\/ki-protokoll\/claude-hook\/block_direct_db.py\",\n \"timeout\": 5\n }\n ]\n }\n ]\n }\n}<\/code><\/pre>\n\n<h2>Sicherheitsschichten (Defense in Depth)<\/h2>\n\n<table>\n <tr><th>Schicht<\/th><th>Mechanismus<\/th><th>Schutz vor<\/th><\/tr>\n <tr>\n <td><strong>1. Claude Code Hook<\/strong><\/td>\n <td>block_direct_db.py (Exit Code 2)<\/td>\n <td>Direkte Bash-Befehle mit mysql\/mariadb<\/td>\n <\/tr>\n <tr>\n <td><strong>2. Identifier-Validierung<\/strong><\/td>\n <td>Regex ^[a-zA-Z0-9_]+$<\/td>\n <td>SQL-Injection über Namen<\/td>\n <\/tr>\n <tr>\n <td><strong>3. Mandatory WHERE<\/strong><\/td>\n <td>where dict Pflicht<\/td>\n <td>Versehentliches UPDATE\/DELETE aller Zeilen<\/td>\n <\/tr>\n <tr>\n <td><strong>4. Default LIMIT<\/strong><\/td>\n <td>LIMIT 100 bei DELETE<\/td>\n <td>Massenlöschung<\/td>\n <\/tr>\n <tr>\n <td><strong>5. DDL-Whitelist<\/strong><\/td>\n <td>ExecuteValidator<\/td>\n <td>Unerlaubte DDL-Statements<\/td>\n <\/tr>\n <tr>\n <td><strong>6. Prepared Statements<\/strong><\/td>\n <td>cursor.execute(sql, params)<\/td>\n <td>SQL-Injection über Werte<\/td>\n <\/tr>\n <tr>\n <td><strong>7. DB-Whitelist<\/strong><\/td>\n <td>Config.ALLOWED_DATABASES<\/td>\n <td>Zugriff auf andere Datenbanken<\/td>\n <\/tr>\n <tr>\n <td><strong>8. Audit-Log<\/strong><\/td>\n <td>mcp_log Tabelle<\/td>\n <td>Nachvollziehbarkeit, Incident Response<\/td>\n <\/tr>\n<\/table>\n\n<h2>Keyword Blocklist (db_select)<\/h2>\n<table>\n <tr><th>Kategorie<\/th><th>Keywords<\/th><th>Risiko<\/th><\/tr>\n <tr><td>DML<\/td><td>DELETE, INSERT, UPDATE<\/td><td>Datenmanipulation<\/td><\/tr>\n <tr><td>DDL<\/td><td>DROP, TRUNCATE, ALTER, CREATE, RENAME<\/td><td>Strukturänderung<\/td><\/tr>\n <tr><td>DCL<\/td><td>GRANT, REVOKE<\/td><td>Rechteänderung<\/td><\/tr>\n <tr><td>File-Ops<\/td><td>LOAD_FILE, INTO OUTFILE, INTO DUMPFILE<\/td><td>Dateizugriff<\/td><\/tr>\n <tr><td>DoS<\/td><td>BENCHMARK, SLEEP<\/td><td>Resource Exhaustion<\/td><\/tr>\n<\/table>\n\n<h2>Incident Response<\/h2>\n<table>\n <tr><th>Event<\/th><th>Indikator<\/th><th>Maßnahme<\/th><\/tr>\n <tr>\n <td>Hook blockiert Befehl<\/td>\n <td>PreToolUse:Bash hook error: BLOCKIERT<\/td>\n <td>MCP-DB Tools verwenden<\/td>\n <\/tr>\n <tr>\n <td>WHERE fehlt<\/td>\n <td>status='denied', \"WHERE clause is required\"<\/td>\n <td>where Parameter hinzufügen<\/td>\n <\/tr>\n <tr>\n <td>Ungültiger Identifier<\/td>\n <td>status='denied', \"Invalid column name\"<\/td>\n <td>Spaltenname prüfen<\/td>\n <\/tr>\n <tr>\n <td>Unerlaubtes DDL<\/td>\n <td>status='denied', \"Statement not allowed\"<\/td>\n <td>Nur ALTER\/CREATE\/DROP\/TRUNCATE<\/td>\n <\/tr>\n <tr>\n <td>SQL Injection Versuch<\/td>\n <td>status='denied', Keyword in error_message<\/td>\n <td>Log analysieren<\/td><\/tr>\n<\/table>\n\n<h2>Credential-Management<\/h2>\n\n<h3>.env Datei<\/h3>\n<pre><code># Berechtigungen setzen\nchmod 600 \/opt\/mcp-servers\/mcp-db\/.env\nchown root:root \/opt\/mcp-servers\/mcp-db\/.env<\/code><\/pre>\n\n<h3>Keine Credentials in Claude Config<\/h3>\n<pre><code># Registrierung OHNE Credentials\nclaude mcp add mcp-db \\\n --transport stdio \\\n -- \/opt\/mcp-servers\/mcp-db\/venv\/bin\/python \\\n \/opt\/mcp-servers\/mcp-db\/server.py\n\n# Credentials werden aus .env geladen<\/code><\/pre>\n\n<h2>Verwandte Kapitel<\/h2>\n<ul>\n <li><a href=\"\/docs\/mcp\/mcp-db\/mcp-db-tools\">Tools<\/a> - Tool-Referenz<\/li>\n <li><a href=\"\/docs\/mcp\/mcp-db\/mcp-db-validators\">Validators<\/a> - Implementierung<\/li>\n <li><a href=\"\/docs\/mcp\/mcp-db\/mcp-db-cheatsheet\">Cheat-Sheet<\/a> - Migration<\/li>\n <li><a href=\"\/docs\/betrieb\/claude-hooks\">Claude Hooks<\/a> - Hook-Dokumentation<\/li>\n<\/ul>"
}
}
{
"tool_response": [
{
"type": "text",
"text": "{\n \"success\": true,\n \"doc\": {\n \"id\": 40,\n \"parent_id\": 36,\n \"slug\": \"mcp-db-security\",\n \"path\": \"\/mcp\/mcp-db\/mcp-db-security\",\n \"title\": \"Sicherheit\",\n \"description\": \"Vollständige Sicherheitsmaßnahmen und DB-User Hardening.\",\n \"content\": \"<nav class=\\\"breadcrumb\\\">\\n <a href=\\\"\/docs\\\">Dokumentation<\/a> » <a href=\\\"\/docs\/mcp\/mcp-db\\\">MCP-DB<\/a> » Sicherheit\\n<\/nav>\\n\\n<h1>MCP-DB Sicherheit<\/h1>\\n<p>Vollständige Sicherheitsmaßnahmen für 10 MCP-DB Tools.<\/p>\\n\\n<h2>Sicherheitsübersicht<\/h2>\\n<table>\\n <tr><th>Maßnahme<\/th><th>Implementierung<\/th><th>Betrifft<\/th><\/tr>\\n <tr><td>Prepared Statements<\/td><td>cursor.execute(query, params)<\/td><td>Alle Tools<\/td><\/tr>\\n <tr><td>Identifier-Validierung<\/td><td>Regex ^[a-zA-Z0-9_]+$<\/td><td>INSERT, UPDATE, DELETE<\/td><\/tr>\\n <tr><td>Mandatory WHERE<\/td><td>where dict Pflicht<\/td><td>UPDATE, DELETE<\/td><\/tr>\\n <tr><td>Default LIMIT 100<\/td><td>Automatisch bei DELETE<\/td><td>DELETE<\/td><\/tr>\\n <tr><td>DDL Statement-Validierung<\/td><td>ExecuteValidator<\/td><td>db_execute<\/td><\/tr>\\n <tr><td>Keyword Blocklist (15)<\/td><td>Word Boundaries<\/td><td>db_select<\/td><\/tr>\\n <tr><td>Database Allowlist<\/td><td>ki_dev, ki_content<\/td><td>Alle Tools<\/td><\/tr>\\n <tr><td>Query Timeout<\/td><td>30 Sekunden<\/td><td>db_select<\/td><\/tr>\\n <tr><td>Row Limit<\/td><td>Max 100<\/td><td>db_select<\/td><\/tr>\\n <tr><td>Query Length<\/td><td>Max 2000 Zeichen<\/td><td>db_select<\/td><\/tr>\\n <tr><td>Logging<\/td><td>Jede Operation in mcp_log<\/td><td>Alle Tools<\/td><\/tr>\\n <tr><td>Blocking-Hook<\/td><td>PreToolUse für Bash<\/td><td>mysql\/mariadb CLI<\/td><\/tr>\\n<\/table>\\n\\n<h2>Schreib-Operationen Sicherheit<\/h2>\\n\\n<h3>db_insert<\/h3>\\n<table>\\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\\n <tr><td>Identifier-Validierung<\/td><td>Tabellen- und Spaltennamen: <code>^[a-zA-Z0-9_]+$<\/code><\/td><\/tr>\\n <tr><td>Prepared Statements<\/td><td>Werte als Parameter, nie String-Konkatenation<\/td><\/tr>\\n <tr><td>DB-Whitelist<\/td><td>Nur ki_dev, ki_content erlaubt<\/td><\/tr>\\n<\/table>\\n\\n<pre><code># Sicher: Prepared Statement\\nINSERT INTO `tasks` (`title`, `status`) VALUES (%s, %s)\\n# Mit values: (\\\"Mein Task\\\", \\\"pending\\\")<\/code><\/pre>\\n\\n<h3>db_update<\/h3>\\n<div class=\\\"alert alert-danger\\\">\\n<strong>UPDATE ohne WHERE ist verboten!<\/strong>\\n<\/div>\\n\\n<table>\\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\\n <tr><td>Mandatory WHERE<\/td><td>Leeres where dict → status: \\\"denied\\\"<\/td><\/tr>\\n <tr><td>Identifier-Validierung<\/td><td>Alle Spalten in data und where<\/td><\/tr>\\n <tr><td>Prepared Statements<\/td><td>SET und WHERE Werte als Parameter<\/td><\/tr>\\n<\/table>\\n\\n<pre><code># Erlaubt:\\ndb_update(table=\\\"tasks\\\", data={\\\"status\\\": \\\"done\\\"}, where={\\\"id\\\": 42})\\n\\n# Blockiert (kein WHERE):\\ndb_update(table=\\\"tasks\\\", data={\\\"status\\\": \\\"done\\\"}, where={})\\n# → {\\\"status\\\": \\\"denied\\\", \\\"error\\\": \\\"WHERE clause is required...\\\"}<\/code><\/pre>\\n\\n<h3>db_delete<\/h3>\\n<div class=\\\"alert alert-danger\\\">\\n<strong>DELETE ohne WHERE ist verboten! Default LIMIT: 100<\/strong>\\n<\/div>\\n\\n<table>\\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\\n <tr><td>Mandatory WHERE<\/td><td>Leeres where dict → status: \\\"denied\\\"<\/td><\/tr>\\n <tr><td>Default LIMIT<\/td><td>Automatisch LIMIT 100 wenn nicht angegeben<\/td><\/tr>\\n <tr><td>Identifier-Validierung<\/td><td>Spaltennamen in where<\/td><\/tr>\\n<\/table>\\n\\n<pre><code># Erlaubt:\\ndb_delete(table=\\\"mcp_log\\\", where={\\\"status\\\": \\\"error\\\"}, limit=50)\\n\\n# Blockiert (kein WHERE):\\ndb_delete(table=\\\"mcp_log\\\", where={})\\n# → {\\\"status\\\": \\\"denied\\\", \\\"error\\\": \\\"WHERE clause is required...\\\"}<\/code><\/pre>\\n\\n<h3>db_execute (DDL)<\/h3>\\n<table>\\n <tr><th>Schutz<\/th><th>Implementierung<\/th><\/tr>\\n <tr><td>Statement-Whitelist<\/td><td>ALTER, CREATE, DROP, TRUNCATE<\/td><\/tr>\\n <tr><td>ExecuteValidator<\/td><td>Prüft erstes Keyword<\/td><\/tr>\\n <tr><td>Logging<\/td><td>Statement-Typ in mcp_log<\/td><\/tr>\\n<\/table>\\n\\n<pre><code># Erlaubt:\\ndb_execute(\\\"ALTER TABLE tasks ADD COLUMN priority INT\\\")\\ndb_execute(\\\"CREATE INDEX idx_status ON tasks(status)\\\")\\ndb_execute(\\\"DROP TABLE temp_data\\\")\\ndb_execute(\\\"TRUNCATE TABLE cache\\\")\\n\\n# Blockiert:\\ndb_execute(\\\"SELECT * FROM tasks\\\") # Kein DDL\\ndb_execute(\\\"INSERT INTO tasks...\\\") # Kein DDL<\/code><\/pre>\\n\\n<h2>Identifier-Validierung<\/h2>\\n<p>Verhindert SQL-Injection über Tabellen-\/Spaltennamen:<\/p>\\n\\n<pre><code>def _validate_identifier(name: str) -> bool:\\n \\\"\\\"\\\"Validiert Tabellen-\/Spaltennamen gegen SQL-Injection.\\\"\\\"\\\"\\n return bool(re.match(r\\\"^[a-zA-Z0-9_]+$\\\", name))<\/code><\/pre>\\n\\n<table>\\n <tr><th>Eingabe<\/th><th>Valide<\/th><th>Grund<\/th><\/tr>\\n <tr><td>tasks<\/td><td>Ja<\/td><td>Alphanumerisch<\/td><\/tr>\\n <tr><td>chat_sessions<\/td><td>Ja<\/td><td>Mit Underscore<\/td><\/tr>\\n <tr><td>tasks; DROP TABLE--<\/td><td>Nein<\/td><td>Sonderzeichen<\/td><\/tr>\\n <tr><td>tasks`<\/td><td>Nein<\/td><td>Backtick<\/td><\/tr>\\n<\/table>\\n\\n<h2>Blocking-Hook (PreToolUse)<\/h2>\\n<p class=\\\"alert alert-danger\\\"><strong>KRITISCH:<\/strong> Direkte mysql\/mariadb-Befehle werden auf System-Ebene blockiert!<\/p>\\n\\n<h3>Blockierte Muster<\/h3>\\n<pre><code># Blockierte Befehle (Beispiele)\\nmysql -u root -pPassword123 -e \\\"SELECT 1\\\"\\nmariadb -u user -pSecret\\nmysql --password=geheim --execute=\\\"DROP TABLE users\\\"\\nmysqldump ki_protokoll > backup.sql\\nsudo mysql -u root -pPass\\n\\n# Stattdessen MCP-DB verwenden:\\ndb_select - SELECT-Abfragen\\ndb_insert - Datensätze einfügen\\ndb_update - Datensätze ändern\\ndb_delete - Datensätze löschen\\ndb_execute - DDL (ALTER\/CREATE\/DROP)\\ndb_describe - Tabellenstruktur\\ndb_databases - Datenbanken auflisten\\ndb_tables - Tabellen auflisten\\ndb_schema - Tabellen-Metadaten\\ndb_stats - MCP-Log Statistiken<\/code><\/pre>\\n\\n<h3>Hook-Konfiguration<\/h3>\\n<p>Pfad: <code>\/var\/www\/.claude\/settings.local.json<\/code><\/p>\\n\\n<pre><code>{\\n \\\"hooks\\\": {\\n \\\"PreToolUse\\\": [\\n {\\n \\\"matcher\\\": \\\"Bash\\\",\\n \\\"hooks\\\": [\\n {\\n \\\"type\\\": \\\"command\\\",\\n \\\"command\\\": \\\"\/var\/www\/tools\/ki-protokoll\/claude-hook\/block_direct_db.py\\\",\\n \\\"timeout\\\": 5\\n }\\n ]\\n }\\n ]\\n }\\n}<\/code><\/pre>\\n\\n<h2>Sicherheitsschichten (Defense in Depth)<\/h2>\\n\\n<table>\\n <tr><th>Schicht<\/th><th>Mechanismus<\/th><th>Schutz vor<\/th><\/tr>\\n <tr>\\n <td><strong>1. Claude Code Hook<\/strong><\/td>\\n <td>block_direct_db.py (Exit Code 2)<\/td>\\n <td>Direkte Bash-Befehle mit mysql\/mariadb<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>2. Identifier-Validierung<\/strong><\/td>\\n <td>Regex ^[a-zA-Z0-9_]+$<\/td>\\n <td>SQL-Injection über Namen<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>3. Mandatory WHERE<\/strong><\/td>\\n <td>where dict Pflicht<\/td>\\n <td>Versehentliches UPDATE\/DELETE aller Zeilen<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>4. Default LIMIT<\/strong><\/td>\\n <td>LIMIT 100 bei DELETE<\/td>\\n <td>Massenlöschung<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>5. DDL-Whitelist<\/strong><\/td>\\n <td>ExecuteValidator<\/td>\\n <td>Unerlaubte DDL-Statements<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>6. Prepared Statements<\/strong><\/td>\\n <td>cursor.execute(sql, params)<\/td>\\n <td>SQL-Injection über Werte<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>7. DB-Whitelist<\/strong><\/td>\\n <td>Config.ALLOWED_DATABASES<\/td>\\n <td>Zugriff auf andere Datenbanken<\/td>\\n <\/tr>\\n <tr>\\n <td><strong>8. Audit-Log<\/strong><\/td>\\n <td>mcp_log Tabelle<\/td>\\n <td>Nachvollziehbarkeit, Incident Response<\/td>\\n <\/tr>\\n<\/table>\\n\\n<h2>Keyword Blocklist (db_select)<\/h2>\\n<table>\\n <tr><th>Kategorie<\/th><th>Keywords<\/th><th>Risiko<\/th><\/tr>\\n <tr><td>DML<\/td><td>DELETE, INSERT, UPDATE<\/td><td>Datenmanipulation<\/td><\/tr>\\n <tr><td>DDL<\/td><td>DROP, TRUNCATE, ALTER, CREATE, RENAME<\/td><td>Strukturänderung<\/td><\/tr>\\n <tr><td>DCL<\/td><td>GRANT, REVOKE<\/td><td>Rechteänderung<\/td><\/tr>\\n <tr><td>File-Ops<\/td><td>LOAD_FILE, INTO OUTFILE, INTO DUMPFILE<\/td><td>Dateizugriff<\/td><\/tr>\\n <tr><td>DoS<\/td><td>BENCHMARK, SLEEP<\/td><td>Resource Exhaustion<\/td><\/tr>\\n<\/table>\\n\\n<h2>Incident Response<\/h2>\\n<table>\\n <tr><th>Event<\/th><th>Indikator<\/th><th>Maßnahme<\/th><\/tr>\\n <tr>\\n <td>Hook blockiert Befehl<\/td>\\n <td>PreToolUse:Bash hook error: BLOCKIERT<\/td>\\n <td>MCP-DB Tools verwenden<\/td>\\n <\/tr>\\n <tr>\\n <td>WHERE fehlt<\/td>\\n <td>status='denied', \\\"WHERE clause is required\\\"<\/td>\\n <td>where Parameter hinzufügen<\/td>\\n <\/tr>\\n <tr>\\n <td>Ungültiger Identifier<\/td>\\n <td>status='denied', \\\"Invalid column name\\\"<\/td>\\n <td>Spaltenname prüfen<\/td>\\n <\/tr>\\n <tr>\\n <td>Unerlaubtes DDL<\/td>\\n <td>status='denied', \\\"Statement not allowed\\\"<\/td>\\n <td>Nur ALTER\/CREATE\/DROP\/TRUNCATE<\/td>\\n <\/tr>\\n <tr>\\n <td>SQL Injection Versuch<\/td>\\n <td>status='denied', Keyword in error_message<\/td>\\n <td>Log analysieren<\/td><\/tr>\\n<\/table>\\n\\n<h2>Credential-Management<\/h2>\\n\\n<h3>.env Datei<\/h3>\\n<pre><code># Berechtigungen setzen\\nchmod 600 \/opt\/mcp-servers\/mcp-db\/.env\\nchown root:root \/opt\/mcp-servers\/mcp-db\/.env<\/code><\/pre>\\n\\n<h3>Keine Credentials in Claude Config<\/h3>\\n<pre><code># Registrierung OHNE Credentials\\nclaude mcp add mcp-db \\\\\\n --transport stdio \\\\\\n -- \/opt\/mcp-servers\/mcp-db\/venv\/bin\/python \\\\\\n \/opt\/mcp-servers\/mcp-db\/server.py\\n\\n# Credentials werden aus .env geladen<\/code><\/pre>\\n\\n<h2>Verwandte Kapitel<\/h2>\\n<ul>\\n <li><a href=\\\"\/docs\/mcp\/mcp-db\/mcp-db-tools\\\">Tools<\/a> - Tool-Referenz<\/li>\\n <li><a href=\\\"\/docs\/mcp\/mcp-db\/mcp-db-validators\\\">Validators<\/a> - Implementierung<\/li>\\n <li><a href=\\\"\/docs\/mcp\/mcp-db\/mcp-db-cheatsheet\\\">Cheat-Sheet<\/a> - Migration<\/li>\\n ... [TRUNCATED-4bd2a26997b8b28f]"
}
]
}