SQLFix-Blog
Naturlig sprog til SQL: Sikkerhedstjek, der er vigtige
At oversætte en forespørgsel til SQL er virkelig nyttigt til første udkast, men den automatiske udførelse af modellens output mod en live-database er vejen, hvor et tasteuhyre kan føre til en slettet tabel. Den sikre holdning er designmodus: Modellen foreslår, et menneske eller en sikret pipeline beslutter. SQLForm følger denne designmodus og udfører aldrig, hvad det genererer, uden en valideringsskridt.
1. Begynd med en kun-design-pipeline
Jeg har udviklet SQLForm omkring idéen om, at et sprogmodel er en designassistent og ikke en eksekveringsmotor. Når en bruger spørger „vis mig salget for sidste måned efter region“, returnerer modellen en SELECT-erklæring. Denne erklæring lægges i en designventeliste og sendes aldrig til produktionsconnector. En menneskelig operatør eller en automatiseret port må udtrykkeligt godkende designet, før det forlader ventelisten. Denne adskillelse skaber en klar revisionsspor: hver forespørgsel, der berører data, har en optaget godkendelsesstep.
Design-koøen gemmes i en let tabel med kolonner for bruger-id, tidsstempel, råforespørgsel, genereret SQL og godkendelsesstatus. Når systemet fejler, kan køen afspilles igen, og ingen forespørgsel går tabt. Jeg har valgt denne konstruktion efter at have set, at teams har tabt data, fordi et demomanuskript har udført en SLET-kommando, der har troet, det var en SELECT-kommando. Køen forhindrer denne klasse af fejl ved konstruktion. SQLFix/SQL/SELECT/EXPLAIN/Waffo
2. Genkend ændringsanvisninger, før de når køen
Den første forsvarslinje er en simpel leksikal kontrol. Jeg søger efter token DELETE, UPDATE, INSERT, DROP, TRUNCATE, ALTER, GRANT, REVOKE og CREATE. Hvis en af disse findes, markeres udkastet som ændrende og sættes i en ventetilstand, der kræver en eksplicit godkendelse fra en senior reviewer. Selv et SELECT, der indeholder en WITH-klausul, der kalder en ændrende funktion, genkendes, da kontrollen udføres på den rå SQL-streng, før en analyse finder sted. SQLFix/SQL/SELECT/EXPLAIN/Waffo
Jeg checker også for komma-separatoren. Et semikolon efterfulgt af et andet token betyder, at brugeren muligvis forsøger at lænke operationer sammen. For eksempel ville „SELECT * FROM users; DELETE FROM logs“ passere en naiv SELECT-kun-check, men blive blokeret, da scanneren ser DELETE-tokenet efter det første semikolon.
For at undgå falske positive ved legitime objektnavne (som en kolonne med navnet "delete_flag"), behandler scanneren kun token som nøgleord, hvis de følges af et mellemrum eller en parentes, hvilket svarer til den typiske SQL-syntaks. Dette gør reglen præcis uden at forbyde nyttige betegnelser.
3. Kør udgaver i en skrivbeskyttet sandbox
Så snart et udkast er godkendt, køre jeg det mod en skrivebeskyttet kopi af produktionsformatet. Kopien opdateres hver nat fra primærsystemet og har ingen skriveadgang for forbindelsesrollen, som bruges af SQLForm. Hvis modellen på nogen måde producerer en ændringsanvisning, returnerer databasen en fejl, og ingen data bliver ændret. Dette omdanner en potentiel dyrt fejl til en synlig fejl, som anmelderen kan se med det samme.
Jeg tvinger også skrivebeskyttelsen på forbindelsesniveau ved at angive PostgreSQL-parametret default_transaction_read_only = on for sessionen. I MySQL starter jeg sessionen med SET SESSION TRANSACTION ISOLATION LEVEL READ ONLY;. Disse indstillinger får serveren til at afvise hver skrive-, ændrings- eller sletkommando med en tydelig fejlkode, som jeg viser i brugergrænsefladen.
At bruge en replika har en ekstra fordel: Spørgsmålet kan køres mod let forældede data uden at påvirke SLA'er, og jeg kan overvåge spørgselens længde og ressourceforbrug uden at true produktionsbelastningen. Hvis replikaen bliver forsinket ud over en konfigurerbar grænseværdi, stopper systemet udkastet og underretter godkenderen om, at dataene muligvis ikke er synkroniseret.
4. Parametrede godkendte forespørgsler
Efter at et udkast har bestået en menneskelig gennemgang, flytter jeg SQL-koden til applikationsniveauet som en forberedt erklæring. Den tekst, der er genereret af modellen, bliver til en skabelon, hvor alle brugerspecifikke værdier er bundet som parametre. Jeg binder aldrig rå strengværdier, ikke engang efter godkendelse, da dette genindfører indsmykningsrisikoen, som udkastet oprindeligt skulle undgå. SQLFix/SQL/SELECT/EXPLAIN/Waffo
Jeg følger retningslinjerne for OWASP SQL Injection Prevention Cheat Sheet, der nævner forberedte instruktioner som primær forsvar. I praksis bruger jeg databasestyrings-API'et: pg_prepare / pg_execute til PostgreSQL og PreparedStatement til MySQL. Styringen overtager vedligeholdelsen af escaping og typesikkerhed, så en værdi, der indeholder et anførselsstav eller et semikolon, behandles som data og ikke som SQL.
For at sikre, at skabelonen forbliver gyldig, parser jeg den godkendte SQL-kode med en let SQL-parser (som sqlparse) og kontrollerer, om hver placeholder svarer til en parameterindeks. Hvis parseren finder et vilde token, der ligner en værdi, men ikke er bundet, sendes skitsematerialet tilbage til revision.
5. Menneskelig verificering som kontrollpunkt
Kontrolløren behøver ikke at være SQL-ekspert; kontrollisten er med vilje holdt kort. Først kontrollerer han, om SELECT-listen svarer til de kolonner, der er nævnt i den oprindelige anmodning. Hvis brugeren har bedt om "Samlet omsætning pr. region" og forespørgslen returnerer COUNT(*), markerer kontrolløren dette. For det andet bekræfter han, at der ikke viser sig nogen muterende token, ved at stole på scanneren, men også gennemfører en visuel kontrol for mulig intelligent camouflage. For det tredje kaster han et blik på WHERE-klausulen for at se, om den uforvarende returnerer flere rækker, end det er meningen (f.eks. manglende datofilter, der ville føre til en fuld tabelscan).
Jeg behandler den genererede forespørgsel som et forslag, ligesom jeg ville gennemgå SQL-kode, der er skrevet af et nyt teammedlem. Gennemseeren kan godkende forespørgslen, anmode om en ændring eller afvise den. Hvis han anmoder om en ændring, kan han redigere udkastet direkte i brugergrænsefladen; den redigerede version bliver til et nyt udkast og går igennem de samme gennemgange igen. Denne løkke sikrer, at modellens output aldrig er den endelige autoritet.
Tidsgainen kommer gennem elimineringsbehovet for at skrive boilerplate-SQL fra bunden. Jeg har set, hvordan hold har kunnet reducere tiden, der kræves for at oprette en første forespørgselsdesign, fra ti minutter til under to minutter, mens de på samme tid beholdt en person i løkken for sikkerheden.
Hvad dette ikke er
Jeg påstår ikke, at SQLForm kan genkende enhver mulig fejl. Den leksikale scanner kan omgås ved hjælp af usædvanlige kodninger eller ved at bruge database-specifik syntaks, der ligner en kommentar. En beslutsom angriber kunne oprette en prompt, der får modellen til at udgive en kommando, der bruger en gemt procedure med sideeffekter, som scanneren ikke markerer, fordi procedurenavnet ikke er inkluderet i vores nøgleordliste. Den skrivebeskyttede replika beskytter mod uønskede skriveoperationer, men hvis replikaen er forkert konfigureret og arver skriveadgang, forsvinder sikkerhedsnettet.
En menneskelig gennemgang er afgørende, men gennemgangspersoner kan overse subtile logiske fejl, især hvis forespørgslen er lang eller bruger komplekse vinduefunktioner. Processen reducerer risikoen, eliminerer den dog ikke. Jeg betragter SQLForm som et værktøj til risikoreduktion, ikke som en mirakelkur.
Referenzen
https://cheatsheetseries.owasp.org/cheatsheets/LLM_Prompt_Injection_Prevention_Cheat_Sheet.html
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
https://cwe.mitre.org/data/definitions/798.html
https://cwe.mitre.org/data/definitions/89
Ofte stillede spørgsmål
Kun mod en skrivebeskyttet replika eller med en hård port, der blokerer ændringsforslag. Det automatiske udførelse af genererede SQL-kommandoer mod produktionsmiljøet er vejen, hvor en designfejl bliver til dataforlustring. Hold modellen i en kun-forslagende rolle og undgå SQLFix/SQL/SELECT/EXPLAIN/Waffo-fejl.
En modeldesign er til verifikation usikker indgående data, samme klassificering som CWE-89 SQL-injektion. En skrivebeskyttet rolle betyder, at selv en utilsigtet udførelse ikke kan ændre produktionsdataene.
Nej. Så snart en forespørgsel overføres til applikationskoden, bør forberedte instruktioner anvendes. At sammenføje værdier tilbage i en streng introducerer igen risikoen for injection. Validering og parametre er separate kontroller.
DELETE-, UPDATE-, DROP-, TRUNCATE-kommandoer og tilladelser, der giver adgang, skal aldrig udføres på en auto-udførelsesvej. De kræver en eksplolit, separat godkendelse.
Prøv produktet: SQLForm
2026-09-16 · kun primære kilder · ingen falske trafikmålinger
Relaterede artikler
Parametrerede forespørgsler vs genereret SQL
Udforsk den komplette AI-Micro-SaaS-emne matrix →
Kan NL2SQL køres sikkert i automatisk tilstand?
Kun mod en skrivebeskyttet replika eller med en hård port, der blokerer muterende kommandoer. Det automatiske udførelse af genereret SQL mod produktionen er vejen, hvorpå en designfejl bliver til data-tab.
Hvorfor er en skrivebeskyttet kontekst vigtig? En modeldesign er til verifikationen usikker input, samme klassifikation som CWE-89 SQL-Injection. En skrivebeskyttet rolle betyder, at selv en utilsigtet udførelse ikke kan ændre produktionsdataene. Betyder det at verificere SQL, at jeg kan springe parametreringen over?
En modeldesign er til verifikation usikker input, samme klassifikation som CWE-89 SQL-injektion. En skrivebeskyttet rolle betyder, at selv en utilsigtet udførelse ikke kan ændre produktionsdataene.
Hvilke instruktioner bør en sikkerhedslag som standard blokere?
DELETE-, UPDATE-, DROP-, TRUNCATE- og rettighedstildelingsanvisninger skal aldrig udføres på auto-udførelsesvejen. De kræver en eksplicit, separat godkendelse.
Kun til beslutningsstøtte. Erstattning for en gennemgang af en databaseadministrator eller en produktionslasttest. Ingen ydeevnegarantier. SQLFix/SQL/SELECT/EXPLAIN/Waffo oversættelse: Kun til beslutningsstøtte. Ingen erstatning for en gennemgang af en databaseadministrator eller en produktionslasttest. Ingen ydeevnegarantier. Vedrørende SQLFix, SQL, SELECT, EXPLAIN og Waffo.