← nitronium.dev
MCP server'da NL→SQL expose ederken güvenlik kontrol listesi
2026-06-06
Kullanıcıya (veya AI agent'a) doğal dil sorusu yazıp SQL döndüren bir tool açıyorsan:
1. localOnly: true flag'i koy
HTTP üzerinden OAuth token'la erişilebilen bir endpoint olmamalı. Tool sadece local MCP (stdio) üzerinden çağrılabilir olsun.
2. SELECT/WITH dışını blokla
`typescript
if (!/^\s*(with|select)\b/i.test(sql)) throw new Error('Only SELECT/WITH allowed');
`
3. Tablo allowlist — ama dikkatli
Regex allowlist yeterli değil (CTE shadow bypass mümkün). Minimum: CTE isimlerini restricted tablolarla çapraz kontrol et. İdeal: SQL parse tree.
4. Tehlikeli fonksiyonları blokla
`typescript
const BLOCKED = /\b(pg_sleep|current_setting|set_config|pg_read_file|
pg_cancel_backend|pg_terminate_backend|dblink|lo_import)\b/i;
`
pg_sleep timing-based exfiltration için kullanılır. current_setting GUC parametrelerindeki secret'ları okur.
5. Statement timeout
`typescript
await engine.executeRaw("SET statement_timeout = '500ms'", []);
try { rows = await engine.executeRaw(sql, []); }
finally { await engine.executeRaw('RESET statement_timeout', []).catch(() => {}); }
`
pg_sleep regex'ten kaçarsa bile 500ms'de timeout olur.
6. Defense-in-depth: read-only DB role
Kod katmanı bypass edilse bile DB katmanı engeller:
`sql
CREATE ROLE query_role NOLOGIN;
GRANT SELECT ON pages, content_chunks, links TO query_role;
-- access_tokens, oauth_clients: intentionally dışarıda
`
LLM-generated SQL exposed etmek istiyorsan bu kontrollerin hepsi gerekli. Herhangi biri tek başına yetmez.
---