SQLFix-Blog

Natürliche Sprache zu SQL: Sicherheitsprüfungen, die wichtig sind

Die Übersetzung einer Frage in SQL ist wirklich nützlich für erste Entwürfe, aber die automatische Ausführung der Modellausgabe gegen eine Live-Datenbank ist der Weg, wie ein Tippfehler zu einer gelöschten Tabelle wird. Die sichere Haltung ist der Entwurfsmodus: Das Modell schlägt vor, ein Mensch oder eine gesicherte Pipeline entscheidet. SQLForm folgt diesem Entwurfsmodus und führt nie aus, was es generiert, ohne eine Überprüfungsschritt.

1. Beginnen Sie mit einer nur-Entwurfs-Pipeline

Ich habe SQLForm um die Idee herum entwickelt, dass ein Sprachmodell ein Entwurfsassistent und kein Ausführungsmotor ist. Wenn ein Benutzer „zeige mir den Umsatz des letzten Monats nach Region“ fragt, gibt das Modell eine SELECT-Anweisung zurück. Diese Anweisung wird in eine Entwurfswarteschlange gelegt und niemals an den Produktionsconnector gesendet. Ein menschlicher Operator oder ein automatisiertes Tor muss den Entwurf ausdrücklich genehmigen, bevor er die Warteschlange verlässt. Diese Trennung schafft eine klare Audit-Spur: jede Abfrage, die Daten berührt, hat einen aufgezeichneten Genehmigungsschritt.

Die Entwurfswarteschlange wird in einer leichten Tabelle mit Spalten für Benutzer-ID, Zeitstempel, Rohanfrage, generiertes SQL und Genehmigungsstatus gespeichert. Wenn das System abstürzt, kann die Warteschlange erneut abgespielt werden und keine Abfrage geht verloren. Ich habe diese Konstruktion gewählt, nachdem ich gesehen habe, dass Teams Daten verloren haben, weil ein Demoskript eine DELETE-Anweisung ausgeführt hat, die das Modell für eine SELECT-Anweisung gehalten hat. Die Warteschlange verhindert diese Klasse von Fehlern durch Konstruktion.

2. Erkennen Sie ändernde Anweisungen, bevor sie die Warteschlange erreichen

Die erste Verteidigungslinie ist eine einfache lexikalische Überprüfung. Ich suche nach den Token DELETE, UPDATE, INSERT, DROP, TRUNCATE, ALTER, GRANT, REVOKE und CREATE. Wenn eines davon gefunden wird, wird der Entwurf als ändernd markiert und in einen Haltezustand versetzt, der eine explizite Genehmigung durch einen senior Reviewer erfordert. Selbst ein SELECT, das eine WITH-Klausel enthält, die eine ändernde Funktion aufruft, wird erkannt, da die Überprüfung auf der rohen SQL-Zeichenfolge durchgeführt wird, bevor eine Analyse erfolgt.

Ich überprüfe auch auf Anweisungstrenner. Ein Semikolon, gefolgt von einem anderen Token, bedeutet, dass der Benutzer möglicherweise versucht, Operationen zu verketten. Zum Beispiel würde „SELECT * FROM users; DELETE FROM logs“ eine naive SELECT-nur-Überprüfung passieren, wird aber blockiert, da der Scanner das DELETE-Token nach dem ersten Semikolon sieht.

Um falsche Positives bei legitimen Objektnamen (wie einer Spalte namens „delete_flag“) zu vermeiden, behandelt der Scanner Token nur dann als Schlüsselwörter, wenn sie von einem Leerzeichen oder einer Klammer gefolgt werden, was der typischen SQL-Grammatik entspricht. Dies hält die Regel präzise, ohne nützliche Bezeichner zu verbieten.

3. Entwürfe in einem schreibgeschützten Sandbox ausführen

Sobald ein Entwurf genehmigt ist, führe ich ihn gegen eine schreibgeschützte Replika des Produktionschemas aus. Die Replika wird jede Nacht aus dem Primärsystem aktualisiert und hat keine Schreibberechtigungen für die Verbindungrolle, die von SQLForm verwendet wird. Wenn das Modell irgendwie eine ändernde Anweisung erzeugt, gibt die Datenbank einen Fehler zurück und keine Daten werden geändert. Dies verwandelt einen potenziell teuren Fehler in einen sichtbaren Fehler, den der Rezensent sofort sehen kann.

Ich erzwinge auch die schreibgeschützte Eigenschaft auf Verbindungsebene, indem ich den PostgreSQL-Parameter default_transaction_read_only = on für die Sitzung festlege. In MySQL starte ich die Sitzung mit SET SESSION TRANSACTION ISOLATION LEVEL READ ONLY;. Diese Einstellungen verursachen, dass der Server jeden Schreib-, Änder- oder Löschbefehl mit einem klaren Fehlercode ablehnt, den ich in der Benutzeroberfläche anzeigen lasse.

Die Verwendung einer Replika hat einen zusätzlichen Vorteil: Die Abfrage kann gegen leicht veraltete Daten ausgeführt werden, ohne dass dies die SLAs beeinträchtigt, und ich kann die Abfrigelänge und die Ressourcennutzung überwachen, ohne dass die Produktionslast gefährdet wird. Wenn die Replika über einen konfigurierbaren Schwellenwert hinaus in Verzug gerät, hält das System den Entwurf an und benachrichtigt den Genehmiger, dass die Daten möglicherweise nicht synchron sind.

4. Parameterisieren genehmigter Abfragen

Nachdem ein Entwurf die menschliche Überprüfung bestanden hat, verschiebe ich den SQL-Code in die Anwendungsebene als vorbereitete Anweisung. Der vom Modell generierte Text wird zu einer Vorlage, in der alle benutzerspezifischen Werte als Parameter gebunden werden. Ich verbinde niemals rohe Zeichenfolgen, auch nicht nach der Genehmigung, da dies das Einschleusungsrisiko wieder einführt, das der Entwurf eigentlich vermeiden sollte.

Ich folge den Richtlinien des OWASP SQL Injection Prevention Cheat Sheet, der vorbereitete Anweisungen als primäre Verteidigung auflistet. In der Praxis verwende ich die native API des Datenbanktreibers: pg_prepare / pg_execute für PostgreSQL und PreparedStatement für MySQL. Der Treiber übernimmt die Pflege von Escaping und Typsicherheit, sodass ein Wert, der ein Anführungszeichen oder ein Semikolon enthält, als Daten und nicht als SQL behandelt wird.

Um sicherzustellen, dass die Vorlage gültig bleibt, parse ich den genehmigten SQL-Code mit einem leichten SQL-Parser (wie sqlparse) und überprüfe, ob jeder Platzhalter einem Parameterindex entspricht. Wenn der Parser ein verirrtes Token findet, das wie ein Wert aussieht, aber nicht gebunden ist, wird der Entwurf zur Überarbeitung zurückgesandt.

5. Menschliche Überprüfung als Kontrollpunkt

Der Überprüfer muss kein SQL-Experte sein; die Checkliste ist absichtlich kurz gehalten. Zuerst überprüft er, ob die SELECT-Liste den in der ursprünglichen Anfrage genannten Spalten entspricht. Wenn der Benutzer nach „Gesamtumsatz pro Region“ gefragt hat und die Abfrage COUNT(*) zurückgibt, markiert der Überprüfer dies. Zweitens bestätigt er, dass kein mutierendes Token erscheint, indem er sich auf den Scanner verlässt, aber auch eine visuelle Überprüfung auf mögliche clevere Verschleierung durchführt. Drittens wirft er einen Blick auf die WHERE-Klausel, um zu sehen, ob sie unbeabsichtigt mehr Zeilen zurückgibt, als beabsichtigt (z. B. fehlender Datum-Filter, der zu einem vollständigen Tabellenscan führen würde).

Ich behandle die generierte Abfrage als Vorschlag, genau wie ich SQL-Code überprüfen würde, der von einem neuen Teammitglied geschrieben wurde. Der Überprüfer kann die Abfrage genehmigen, eine Änderung anfordern oder ablehnen. Wenn er eine Änderung anfordert, kann er den Entwurf direkt in der Benutzeroberfläche bearbeiten; die bearbeitete Version wird zu einem neuen Entwurf und durchläuft die gleichen Überprüfungen erneut. Diese Schleife stellt sicher, dass die Ausgabe des Modells niemals die endgültige Autorität ist.

Der Zeitgewinn kommt durch die Eliminierung der Notwendigkeit, Boilerplate-SQL von Grund auf zu schreiben. Ich habe gesehen, wie Teams die Zeit, die benötigt wird, um einen ersten Abfrageentwurf zu erstellen, von zehn Minuten auf unter zwei Minuten reduzieren konnten, während sie gleichzeitig einen Menschen in der Schleife für die Sicherheit behielten.

Was dies nicht ist

Ich behaupte nicht, dass SQLForm jeden möglichen Fehler erkennt. Der lexikale Scanner kann durch ungewöhnliche Kodierungen oder durch die Verwendung von datenbank-spezifischer Syntax, die wie ein Kommentar aussieht, umgangen werden. Ein entschlossener Angreifer könnte einen Prompt erstellen, der das Modell dazu bringt, eine Anweisung auszugeben, die einen gespeicherten Prozess mit Nebeneffekten verwendet, den der Scanner nicht markiert, weil der Prozedurname nicht in unserer Schlüsselwortliste enthalten ist. Die schreibgeschützte Replika schützt vor unbeabsichtigten Schreibvorgängen, aber wenn die Replika falsch konfiguriert ist und Schreibrechte erbt, verschwindet das Sicherheitsnetz.

Eine menschliche Überprüfung ist unerlässlich, aber Überprüfer können subtile Logikfehler übersehen, insbesondere wenn die Abfrage lang ist oder komplexe Fensterfunktionen verwendet. Der Prozess reduziert das Risiko, eliminiert es jedoch nicht. Ich betrachte SQLForm als ein Risikominderungstool, nicht als eine Wunderwaffe.

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

Häufig gestellte Fragen

Nur gegen eine schreibgeschützte Replika oder mit einem harten Gate, das ändernde Anweisungen blockiert. Das automatische Ausführen generierter SQL-Anweisungen gegen die Produktionsumgebung ist der Weg, auf dem ein Entwurfsfehler zu Datenverlust wird. Halten Sie das Modell in einer nur-vorschlagenden Rolle.

Ein Modellentwurf ist bis zur Überprüfung unvertrauenswürdiges Eingabedaten, derselbe Klassifikation wie CWE-89 SQL-Injection. Eine schreibgeschützte Rolle bedeutet, dass sogar eine versehentliche Ausführung die Produktionsdaten nicht ändern kann.

Nein. Sobald eine Abfrage in den Anwendungscode übernommen wird, sollten vorbereitete Anweisungen verwendet werden. Das Zusammenfügen von Werten zurück in eine Zeichenfolge führt das Risiko von Injection wieder ein. Überprüfung und Parametrisierung sind separate Kontrollen.

DELETE-, UPDATE-, DROP-, TRUNCATE-Anweisungen und berechtigungsgebende Anweisungen sollten niemals in einem Auto-Ausführungspfad ausgeführt werden. Sie erfordern eine explizite, separate Genehmigung.

Probieren Sie das Produkt: SQLForm

2026-09-16 · nur primäre Quellen · keine gefälschten Traffic-Metriken

Verwandte Artikel

Parameterisierte Abfragen vs generierter SQL

Erkunden Sie die vollständige AI-Micro-SaaS-Themenmatrix →

Kann NL2SQL sicher im Automatikmodus ausgeführt werden?

Nur gegen eine schreibgeschützte Replika oder mit einem harten Gate, das mutierende Anweisungen blockiert. Das automatische Ausführen von generiertem SQL gegen die Produktion ist der Weg, wie ein Entwurfsfehler zu Datenverlust wird. Halten Sie das Modell in einer propose-only-Rolle.

Warum ist ein schreibgeschützter Kontext wichtig? Ein Modellentwurf ist bis zur Überprüfung unvertrauenswürdiges Eingabe, derselbe Klassifikation wie CWE-89 SQL-Injection. Eine schreibgeschützte Rolle bedeutet, dass selbst eine versehentliche Ausführung die Produktionsdaten nicht ändern kann. Bedeutet das Überprüfen von SQL, dass ich die Parametrisierung überspringen kann?

Ein Modellentwurf ist bis zur Überprüfung unvertrauenswürdiges Eingabe, derselbe Klassifikation wie CWE-89 SQL-Injection. Eine schreibgeschützte Rolle bedeutet, dass selbst eine versehentliche Ausführung die Produktionsdaten nicht ändern kann.

Welche Anweisungen sollte eine Sicherheitsschicht standardmäßig blockieren?

DELETE-, UPDATE-, DROP-, TRUNCATE- und Rechte-vergebende Anweisungen sollten niemals im Auto-Ausführungspfad ausgeführt werden. Sie erfordern eine explizite, separate Genehmigung.

Nur zur Entscheidungsunterstützung. Kein Ersatz für eine Überprüfung durch einen Datenbankadministrator oder eine Produktionslasttestung. Keine Leistungsgarantien.

← Zurück zum Blog

War dieses Ergebnis hilfreich?Feedback