← nitronium.dev
Regex ile SQL güvenlik kontrolü neden yetmez
2026-06-06
LLM'in ürettiği SQL'i regex ile kontrol etmek cazip çünkü kolay. Ama regex SQL'in yapısını anlamaz, sadece metni görür. Bu yüzden her ciddi kısıtlamanın bir bypass yolu var.
Subquery bypass
FROM (SELECT * FROM access_tokens) — outer FROM'dan tablo ismini göremezsin.
Genellikle çözüm: subquery'leri tamamen yasakla, CTEs ile yönlendir. Ama bu da kendi sorununu getiriyor.
CTE shadow bypass
`sql
WITH access_tokens AS (SELECT * FROM access_tokens)
SELECT * FROM access_tokens
`
CTE alias'ını gerçek tablo referansından ayırt edemezsin. Regex hangi FROM'un CTE body'si içinde olduğunu bilemez.
Schema qualification
public.access_tokens veya "access_tokens" — tablo ismi regex'ine uymaz, allowlist'i atlar.
Yorum injection
`sql
SELECT FR/bypass*/OM access_tokens
`
Naive regex için bu geçerli SQL değil gibi görünür ama Postgres çalıştırır.
Timing channel
pg_sleep regex'te yakalanmamışsa veya obfuscate edilmişse timing-based exfiltration mümkün. Her bit için response time farklı.
---
Ne yapmalı?
Regex guard'ı tamamen bırakma ama tek savunma hattı yapma:
1. Parse tree — node-sql-parser veya pg_query ile AST; CTE body, subquery, schema qualification otomatik ayrılır.
2. DB-level role — kod katmanı bypass edilse bile DB'nin GRANT'ı kısıtlar.
3. Statement timeout — timing attack'ı engellemek için SET statement_timeout = '500ms'.
Regex pattern matching ile güvenlik sağlamaya çalışmak tüm edge case'leri önceden bilmeyi gerektirir. SQL için bu pratik değil.
---