← 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 treenode-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.

---