PRODEgemen Avrupa BaaS platformuKontrol Panelini Aç →

Yerel yapay zeka · 9 dk. okuma

NL2SQL'i LLM SQL enjeksiyonuna karşı güvenli hale getirin

Affane Daylami · Fondateur · 16 Nisan 2026

Bloga geri dön

NL2SQL uç noktası, doğal dil sorusunu bir SQL sorgusuna dönüştürür ve ardından bu sorgu veritabanınızda yürütülür. Bu nedenle risk, bir formda kötü şekilde kaçan bir dize olan klasik SQL enjeksiyonu değildir: hangi SQL'in yazılacağına tek başına karar veren bir dil modelidir. Modelden kibarca sistem isteminde yalnızca SELECT oluşturmasını istemek yapısal olarak hiçbir şeyi engellemez, bu bir talimattır, erişim kontrolü değil. İşe yarayan tek yöntem, daha sonra oluşturulan SQL'i sözdizimsel ağacını oluşturan bir ayrıştırıcıyla doğrulamaktır.

Bu İngilizce metin, Fransızca orijinalinden otomatik olarak oluşturulmuştur ve henüz incelenmemiştir.
Bu sayfa otomatik olarak çevrildi. İngilizce versiyonu yetkilidir.

This guide details the method that actually works: structural restriction to SELECT, closed whitelist of functions, mandatory row cap, and locking of the queried schema. Each step relies on the validator actually implemented in Aurabase's NL2SQL engine, a capability of its native AI built into thebackend, not a third-party service thrown together after the fact. If the subject is new to you, our overview of NL2SQL lays the foundations, and the step-by-step tutorial shows how to build the complete endpoint.

Temeller

  • Hızlı mühendislik (“yalnızca SELECT oluşturur”) bir güvenlik kontrolü değildir: bir model halüsinasyon görebilir, belirsiz bir soru tarafından yönlendirilebilir veya talimatları görmezden gelebilir.
  • Geçerli olan doğrulama yapısaldır: Bir ayrıştırıcı, isteğin sözdizimsel ağacını (AST) oluşturur ve açıkça yetkilendirilmeyen her şeyi varsayılan olarak reddeder.
  • Dört somut katman riski sınırlandırır: katı SELECT (ne alt sorgu, ne CTE, ne de UNION), on işlevden oluşan kapalı beyaz liste, LIMIT zorunlu ve sınırlı, sistem kataloğuna erişimin engellenmesi ve kiracı olmayan şemalar.
  • Sorgulanan şema sunucudan gelmelidir, asla istemci isteğindeki bir alandan gelmemelidir: aksi halde hiçbir şey arayan kişinin doğrulamayı atlamak için kendi şemasını sağlamasını engellemez.
  • Aurabase'de bu doğrulayıcı (Pas sandığı sqlparser), kodda belgelenen çekişmeli durumlarla test edilir: FILTER, toplu bir ORDER BYveya OFFSETiçinde gizlenmiş yasaklanmış işlevler.
#
Asıl sorun

Sistem istemindeki bir talimat neden hiçbir şeyi engellemiyor?

"Yalnızca SELECT sorguları oluşturur" diyen sistem istemi bir engel değil, bir tercihtir. Model, teknik bir kısıtlamanın fiziksel olarak başka bir şey yazmasını engellemesi nedeniyle değil, talimatları takip etmek üzere eğitildiği için çoğu zaman buna saygı duyar. İki tür başarısızlık, üretimde bu güveni yetersiz kılmaktadır.

İlki sorunun kendisinden geliyor. Kötü niyetli veya formülasyonunda yaratıcı olan bir kullanıcı, soruyu, yazmaması gereken bir modeli SQL'e doğru itecek şekilde yönlendirebilir: hassas bir tabloya birleştirme, beklenen mantığı atlatan bir filtre, bir sistem işlev çağrısı. Model, meşru bir soru ile onu manipüle etmek için tasarlanmış bir soru arasında ayrım yapmıyor.

İkincisi kötü niyetli olmayı gerektirmez. Bir model, bir tablo adının halüsinasyonunu yapabilir, istemin istediği LIMIT değerini unutabilir veya büyük bir tabloda herhangi bir kısıtlama olmaksızın bir SELECT * oluşturabilir. Sonuç her iki durumda da aynıdır: Bilgi istemi filtresini geçen ve gerçek bir veritabanında yürütülmek üzere olan potansiyel olarak pahalı veya müdahaleci SQL.

Yardımcı olan görüntü

Sistem istemi yararlı olmayı sürdürür ve çoğu zaman modeli doğru sonuca yönlendirir. Ancak "erişim yok" işareti, okumayı bilmeyen veya onu görmezden gelmeye karar veren hiç kimseyi durdurmaz. Sadece ön panele değil, arka tarafta kapalı bir kapıya ihtiyacınız var.

#
1. Adım

Oluşturulan SQL'i asla ham bir dizeye değil, bir sözdizimi ağacına ayrıştırın

İlk savunma hattı, model tarafından üretilen SQL'i hedef lehçe için gerçek bir ayrıştırıcıyla ayrıştırmak, ardından ham metni değil, ortaya çıkan yapıyı doğrulamaktır. Karakter dizisinde ("DROP", "DELETE", ";") yasaklı kelimelerin aranması önemsiz bir şekilde atlanır: farklı büyük/küçük harf, bir anahtar kelimenin ortasına eklenen yorum, yazılan tırnak işaretleri. Bir sözdizimi ağacı, sorgunun gerçekte ne yaptığını açık bir şekilde açıklar.

Aurabase bu adımı Rust sandığı sqlparser ve onun lehçesi PostgreSqlDialectile uygular. Ayrıştırmadan önce bile, ilk sözcüksel filtre ağaçta bir kez doğru şekilde akıl yürütmesi zor olan iki yapıyı reddeder: bir dizedeki keyfi içeriği gizleyebilen dolar alıntısı ($$...$$) ve bir talimatın gerçek sonunu gizleyebilen çok satırlı yorumlar (/* */).

nl2sql/validator.rsrust
let dialect = PostgreSqlDialect {};
let mut statements = Parser::parse_sql(&dialect, sql)
    .map_err(|e| AuraError::BadRequest(format!("Erreur de parsing SQL: {}", e)))?;

if statements.len() > 1 {
    return Err(AuraError::BadRequest("Multi-statements non autorisés".to_string()));
}

Çoklu ifadenin bu şekilde reddedilmesi, SQL enjeksiyonunun en iyi bilinen formunu istifleme yoluyla engeller: SELECT * FROM users; DROP TABLE users;--. Ayrıştırıcı yalnızca eyleme geçirilebilir bir talimat döndürür, orijinal soruda nasıl ifade edilirse edilsin ikincisine asla ulaşılamaz.

#
2. Adım

Yapısal olarak basit bir SELECT ile sınırlandırın

Ağaç elde edildikten sonra, en geniş doğrulama yalnızca bir tür kök düğümü, bir sorguyu (Statement::Query) kabul etmek ve diğer her şeyi reddetmektir: INSERT, UPDATE, DELETE, DROP, CREATE, ALTER. Bu artık hızlı bir talimat değil, çözümlenen nesnenin türüne ilişkin, hiçbir sorunun ustaca formüle edilemeyeceği bir koşuldur.

Bir SELECT içinde bile birçok yapı tehlikeli olmaya devam ediyor ve açıkça reddedilmeyi hak ediyor:

İnşaat reddedildiNeden tehlikelidir?
CTE / İLESon SELECT'ten önce istenmeyen ek mantık zincirlenebilir.
Alt sorgular, UNION / INTERSECT / EXCEPTTek bir sorunun tek bir sorguda yapabileceklerinin yüzey alanını genişletir.
SEÇ... İÇİNEBir tablo oluşturur: Okuma kılığına girmiş yazı.
GÜNCELLEME / PAYLAŞIM İÇİNKilitlerin takılması, üretim trafiğiyle çekişme riski.
Tablo işlevleri (generate_series, pg_read_file...)Talep üzerine oluşturulan hatlar aracılığıyla sisteme erişim veya hizmet reddi.

Depodan alınan bir test senaryosu son noktayı somut olarak göstermektedir: SELECT * INTO backup FROM users, ne görünür yazma anahtar sözcüğü ne de şüpheli işlev içermemesine rağmen reddedilmiştir. Talebin şekli, talebin diskalifiye edilmesi için yeterlidir.

#
3. Adım

İşlev beyaz listesi, kara liste değil

Yasaklanan işlevlerden oluşan bir kara liste (pg_sleep, pg_read_file, dblink...) her tehlikeli işlevin tek tek tahmin edilmesini gerektirirken Postgres bunlardan birkaç yüz tanesini açığa çıkarır. Beyaz liste kanıt yükünü tersine çevirir: yalnızca on işleve izin verilir, count, sum, avg, min, max, lower, upper, coalesce, date_trunc, now. Henüz kimsenin eklemeyi düşünmediği meşru bir özellik de dahil olmak üzere, geri kalan her şeye varsayılan olarak izin verilmez.

Tek bir doğrulama geçişi her zaman yeterli değildir. Ağacın yapısal geçişi, giriş noktalarını tek tek listeler (projeksiyon, WHERE, JOIN, GROUP BY...) ve birini unutmak kolaydır: yasak bir işlev bir FILTER (WHERE pg_sleep(10) IS NOT NULL)yan tümcesinde, bir iç toplama ORDER BY (sum(id ORDER BY pg_sleep(10))), WITHIN GROUP, DISTINCT ONveya OFFSETiçinde gizlenebilir .

nl2sql/tests.rsrust
#[test]
fn test_rejette_fonction_interdite_dans_filter() {
    assert!(validate(
        "SELECT count(*) FILTER (WHERE pg_sleep(10) IS NOT NULL) FROM users",
        None, None
    ).is_err());
}

Bu nedenle Aurabase doğrulayıcı, yapısal yoldan bağımsız olarak, nerede olurlarsa olsunlar ağaçtaki tüm ifadelerin üzerinden geçen ikinci bir kapsamlı geçiş ekler. Bu, varsayılan derinlemesine bir savunmadır: İlk pas bir vakayı kaçırırsa, ikincisi yetişir.

#
4. Adım

Döndürülen satırları bağlayın: LIMIT zorunlu ve sınırlı

SELECT * yetkili kalır, veri madenciliği için faydalıdır. Risk yıldızda değil, bir model tarafından yazılan bir sorguda tavanın olmamasında yatmaktadır: Kötü formüle edilmiş bir soru, bellek maliyeti ve yanıt süresiyle birlikte bütün bir tabloyu geri getirebilir.

Aurabase basit ve şeffaf bir kural uygular. Oluşturulan SQL'de LIMITyoksa sunucu bir tane ekler (varsayılan olarak 100 satır, değer sistem isteminde modele duyurulur). SQL, sabit sınırın ötesinde bir LIMIT talep ederse (varsayılan olarak 1000 satır), sorgu sessizce azaltılmak yerine açıkça reddedilir. Her iki değer de sunucu tarafında yapılandırılabilir (AI_NL2SQL_DEFAULT_LIMIT, AI_NL2SQL_MAX_LIMIT) ve hata tavanı aşarsa sunucu başlatmayı bile reddeder.

réponse /v1/ai/{project_id}/nl2sql (extrait)json
{
  "sql": "SELECT count(*) FROM orders WHERE status = 'paid' LIMIT 100",
  "limit": 100,
  "limit_injected": true
}
Bilgi

Sessizce kesmek yerine reddetmenin doğrudan bir çıkarı var: Bunu belirtmeden uygulanan bir tavan, arayan kişiye talebinin yerine getirildiği yanılsamasını verirken, sonuç onun haberi olmadan kısaltılmış olurdu. limit_injected her zaman değerin modelden mi yoksa sunucudan mı geldiğini söyler.

#
Adım 5

Şemaya erişimi kilitleyin: sistem kataloğu ve çapraz şema

Gerçek bir veritabanına bağlı bir NL2SQL motorunu iki farklı sızıntı tehdit ediyor: Postgres sistem kataloğuna erişim ve arayana ait olmayan bir şemaya erişim. Her ikisi de, aşağı yönde yerleştirilen herhangi bir RLS politikasından bağımsız olarak doğrulama sonrasında bloke olur.

pg_catalog her zaman search_pathöğesinin bir parçasıdır; bu, pg_authid veya pg_stat_activity gibi nitelenmemiş bir adın ona önek olmadan doğrudan eriştiği anlamına gelir. Aurabase doğrulayıcı, nitelikli olsun ya da olmasın, pg_ile başlayan tüm adların yanı sıra information_schema ve dahili şema aura_console'yi de engeller.

İki bileşenli bir adda (schema.table), yalnızca çağıran projenin şemasına izin verilir, diğer değerler reddedilir. Üç veya daha fazla bileşeni olan bir ad otomatik olarak reddedilir. Oluşturulan sorgu düzeyindeki bu sınır,çok kiracılı yalıtımhakkındaki makalemizde ayrıntılı olarak açıklanan veritabanı düzeyi yalıtımına ektir: biri oluşturulan SQL'in başka bir şemayı hedeflemesini engeller, diğeri ise bağlantının kendisinin başka bir veritabanına ulaşmasını engeller. Hiçbiri diğerinin yerini almaz.

#
Adım 6

İstemcinin sorgulanan şemayı yeniden tanımlamasına asla izin verme

İstemcinin sorgusunda izin verilen şema veya tabloları açıklayan bir parametreyi kabul eden herhangi bir NL2SQL API'sini ayrı bir tuzak bekler. İstemi oluşturmak ve SQL çıktısını doğrulamak için aynı parametre kullanılırsa, arayan kişi neye izin verildiği konusunda yalan söyleyebilir ve doğrulama, veritabanının gerçekliği yerine bu yalana göre doğrulama yapar.

Aurabase, performans için otuz saniyelik kısa bir önbellek ile her çağrıda gerçek proje tabanı şemasını inceler ve istek gövdesinde gönderilen herhangi bir schema, allowed_schemaveya schema_context alanını kabul edip ardından sessizce üzerine yazmak yerine açıkça reddeder (400 hata). Aradaki fark önemlidir: Kabul edilen ve sonra göz ardı edilen bir alan, var olmayan bir kontrol yanılsaması verir; reddedilen bir alan bunu hemen söylüyor.

#
Kontrol listesi

Üretimden önce kendi NL2SQL işlem hattınızı denetleyin

İster Aurabase kullanıyor olun, ister genel bir LLM'nin üzerine kendi işlem hattınızı oluşturuyor olun, aşağıdaki noktalar en sık gözden kaçırılan konuları kapsar.

Doğrulayıcıyı kendiniz yazarsanız

  • SQL'i tam lehçeniz için gerçek bir ayrıştırıcıyla ayrıştırın; hiçbir zaman bir dizede desen eşleştirmesi yapmayın.
  • Varsayılan bir reddetmeyi benimseyin: Yalnızca halihazırda tanımlanmış olan tehlikeli durumlar değil, her türlü düğüm, açıkça yetkilendirilmemiş herhangi bir işlev reddedilmelidir.
  • Sorgu başına yalnızca bir ifadeyi kabul edin; bu, yığın sorgularına karşı en basit reddetme yöntemidir.
  • Doğrulayıcıyı yalnızca bariz vakalarla değil, gerçek çekişmeli vakalarla (FILTER'da, toplu bir ORDER BY'de, OFFSET'te yasaklanmış işlev) test edin.
  • Her şeye rağmen, doğrulanmış SQL'i beklenen şemada azaltılmış ayrıcalıklara sahip bir Postgres rolüyle yürütün: doğrulayıcı sorgunun biçimini sınırlar, rol ise bir vakanın kaçması durumunda fiziksel olarak başarabileceklerini sınırlar.

Üçüncü taraf bir NL2SQL çerçevesini değerlendiriyorsanız

  • Doğrulamanın yapısal mı (AST) yoksa yalnızca anlık bir talimat mı olduğunu açıkça sorun: cevap her şeyi değiştirir.
  • Satır sınırının yalnızca masrafları size ait olacak şekilde en iyi uygulama olarak belgelenmekle kalmayıp, varsayılan olarak uygulandığını kontrol edin.
  • Doğrulama için kullanılan şemanın API istemcisi tarafından sağlanıp sağlanamayacağını kontrol edin; bu, yukarıda açıklanan kusurun tam olarak yeniden açılmasına neden olacaktır.
  • Seçim yapmadan önce birkaç aracı bu spesifik kritere göre karşılaştırın: NL2SQL araçları karşılaştırmamız, 2026'da mevcut yaklaşımları ayıran özelliklerin ayrıntılarını verir.
#
Derinlemesine savunma

Doğrulayıcı riski azaltır, RLS'nin yerini almaz

Sağlam bir AST doğrulayıcı, kaynaktaki riski azaltır: Veritabanınıza ulaşan SQL zaten bilinen ve sınırlanmış bir forma sahiptir. Ancak hassas tablolarınızdaki, belirli bir kullanıcının hangi satırları görme hakkına sahip olduğuna karar veren RLS politikalarının yerini almaz. İki katman farklı soruları yanıtlar: Doğrulayıcı, oluşturulan sorgunun biçimini sınırlar, RLS ise belirli bir kullanıcı için döndürebileceği verileri sınırlar. Biri diğerinin yanında gereksiz görünse bile her ikisini de aktif tutun.

NL2SQL covers structured questions about your tables. For questions about unstructured content, documents, notes, tickets, Aurabase's native RAG follows a comparable security logic, detailed in our RAG pipeline tutorial on pgvector.

#
Sıkça Sorulan Sorular

SSS

NL2SQL'in güvenliğini sağlamak için hızlı mühendislik tamamen işe yaramaz mı?+
Hayır, çoğu zaman modeli doğru ve ilgili SQL'e yönlendirmek açısından yararlı olmaya devam ediyor. Ancak bu bir güvenlik kontrolü değildir: belirsiz veya manipüle edilmiş bir soru onu atlayabilir ve hızlı bir talimat fiziksel olarak hiçbir şeyi engellemez. Bilgi isteminin kalitesinden bağımsız olarak, nesilden sonra yapısal doğrulayıcıya ihtiyaç duyulur.
Oluşturulan SQL zaten doğrulanmış ve SELECT ile sınırlandırılmışsa yine de RLS'yi etkinleştirmeli miyiz?+
Evet. Doğrulayıcı, veriler üzerindeki iş haklarını değil, isteğin biçimini (alt sorgu yok, beyaz liste dışı işlev yok, sınırlı LIMIT) sınırlar. RLS, tamamen geçerli bir SELECT dahilinde bile, belirli bir kullanıcının hangi satırları görme hakkına sahip olduğuna karar veren katman olarak kalır.
On işlevden oluşan kapalı bir beyaz liste olası soruları çok fazla sınırlamaz mı?+
Evet ve bu isteğe bağlıdır. Okuma analizlerinin çoğunu (sayım, toplam, ortalama, min, maksimum, alt, üst, birleştirme, date_trunc, şimdi) kapsar ve henüz kimsenin eklemeyi düşünmediği meşru bir işlev de dahil olmak üzere diğer her şeyi varsayılan olarak reddeder. Her ekleme, kara listedeki bir gözetim değil, açık bir karar olmalıdır.

DAĞITILMAYA HAZIR MISINIZ?

Beş dakika içinde arka ucunuz.

Kredi kartı gerekmez · 500 MB ücretsiz · 50.000 MAU