← nitronium.dev
CTE ismiyle SQL allowlist bypass
2026-06-06
SQL allowlist'i regex ile uyguluyorsan CTE isimleri kör noktandır.
`sql
-- Allowed tables: pages, content_chunks, links ...
-- Blocked tables: access_tokens, oauth_clients ...
-- Sıradan bypass:
WITH access_tokens AS (SELECT * FROM access_tokens)
SELECT * FROM access_tokens
`
Regex FROM access_tokens görür, access_tokens'ı CTE alias olarak tanır ve allowlist kontrolünü atlar. Oysa CTE gövdesindeki FROM access_tokens gerçek tabloya gidiyor.
Kök neden: regex hangi FROM'un CTE gövdesi içinde, hangisinin dışarıda olduğunu anlayamaz.
Hızlı fix: CTE isimlerini restricted tablo listesiyle çapraz kontrol et.
`typescript
const BLOCKED_CTE_NAMES = new Set(['access_tokens', 'oauth_clients', ...]);
for (const match of sql.matchAll(/\b(\w+)\s+as\s*\(/gi)) {
if (BLOCKED_CTE_NAMES.has(match[1])) throw new Error('CTE name shadows restricted table');
}
`
Gerçek fix: SQL parse tree kullan. node-sql-parser veya pg_query CTE body'sini ve outer query'yi ayrı node olarak verir, shadow mümkün değil.
---