2016-07-21 3 views
0

Ich benutze Pymssql zum Aktualisieren, Löschen und Hinzufügen von Spalten zu einem MS SQL-Server. Die Spalten sind leider Variablen, die von externen Quellen gesetzt werden, wie z. B. Lesen der Datenbank, Lesen aus einer anderen Datenbank. Jetzt versuche ich zu verhindern, dass "bad" sql durchkommt, da ich nicht genau weiß, was die andere Datenbank mir gibt.Der beste Weg zu verhindern, SQL "Injektion" bei Verwendung der Spalte als Variable

'ALTER TABLE tablenameA ADD [' + columnname + '] varchar(25) NULL' 
'ALTER TABLE tablenameA DROP COLUMN ['+columnname+']' 
('UPDATE tablenameA SET [' + columnname + ']=%s WHERE id = 2', value) 

Jetzt kann ich nicht eine weiße Liste verwenden, wie ich weiß nicht, welche Spaltennamen hinzugefügt werden soll, meine einzige andere Möglichkeit ich denken kann, ist eine schwarze Liste zu verwenden, aber ich frage mich, ob es vielleicht existiert eine dritte Option.

+2

Sie könnten ['QUOTENAME'] verwenden (https://msdn.microsoft.com/en-us/library/ms176114.aspx) –

+0

Aus derselben' QUOTENAME' Dokumentation: * Liefert eine ** Unicode Zeichenkette ** Mit den Trennzeichen, die hinzugefügt wurden, um die Eingabezeichenfolge zu einer gültigen SQL Server-Begrenzungs-ID zu machen. * Eine Zeichenfolge wird hier immer noch nicht ausgeführt, da sie keine vollständige SQL-Anweisung erstellt. –

+0

Würde die Datenbank einmal mit 'SELECT QUOTENAME (% s)' abfragen, dann interpoliere das in die Abfrage do ...? – deceze

Antwort

2

Transact-SQL hat eine Funktion (Die Spaltennamen werden von einer Spalte in einer Tabelle mit Typ String bekommen), um eine SQL-Zeichenfolge in einen sicheren Objektnamen zu drehen: QUOTENAME(). Verwenden Sie es, um einen Bind-Parameter ein ordnungsgemäß zitiert SQL-Objekt der Datenbanktreiber bieten zu haben:

cursor.execute('SELECT QUOTENAME(%s)', (columnname,)) 
quoted_columnname, = next(cursor) 

Jetzt können Sie verwenden dass Zeichenfolge in einer neuen Abfrage:

query = 'ALTER TABLE tablenameA ADD {} varchar(25) NULL'.format(quoted_columnname) 

usw. verwendet I str.format() um die Zeichenfolge hier einzufügen, anstatt String-Verkettung zu verwenden. Beachten Sie, dass die [...] eckigen Klammern nicht mehr benötigt werden; QUOTENAME() hat sich darum gekümmert.

Verwandte Themen