pysqlite3 --- select ... where like ...

Hallo, in der pysqlite3-Doku (Python 2.5) steht zu lesen:
# Never do this -- insecure! symbol = 'IBM' c.execute("... where symbol = '%s'" % symbol)
# Do this instead t = (symbol,) c.execute('select * from stocks where symbol=?', t)
Okay. Geht ja auch meistens. Aber wie schreibe ich denn dann sowas: "select * from xxx where aaa like '%%%s%%' or bbb like '%%%s%%'" % (a, b) Dies funktioniert, aber irgendwie will es bei mir nicht mit dem ?-Platzhalter... Schöne Grüße, Matthias

Matthias Huening <mhuening@zedat.fu-berlin.de> at Tuesday 17 June 2008, 21:53:15
Hallo,
in der pysqlite3-Doku (Python 2.5) steht zu lesen:
# Never do this -- insecure! symbol = 'IBM' c.execute("... where symbol = '%s'" % symbol)
# Do this instead t = (symbol,) c.execute('select * from stocks where symbol=?', t)
Okay. Geht ja auch meistens. Aber wie schreibe ich denn dann sowas:
"select * from xxx where aaa like '%%%s%%' or bbb like '%%%s%%'" % (a, b)
values = ['%%%s%%' % v for v in (a, b)] c.execute("select * from xxx where aaa like ? or bbb like ?", values) -- Freiheit ist immer die Freiheit der Andersdenkenden. (Rosa Luxemburg)

Sebastian Wiesner (17.06.2008 22:32):
"select * from xxx where aaa like '%%%s%%' or bbb like '%%%s%%'" % (a, b)
values = ['%%%s%%' % v for v in (a, b)] c.execute("select * from xxx where aaa like ? or bbb like ?", values)
Ja, natürlich, erst die Prozentzeichen, dann einfügen... So geht's. Danke! (Da hatte ich wohl irgendwie einen Knoten im Kopf...) Schöne Grüße, Matthias

Matthias Huening schrieb:
Hallo,
in der pysqlite3-Doku (Python 2.5) steht zu lesen:
# Never do this -- insecure! symbol = 'IBM' c.execute("... where symbol = '%s'" % symbol)
# Do this instead t = (symbol,) c.execute('select * from stocks where symbol=?', t)
Okay. Geht ja auch meistens. Aber wie schreibe ich denn dann sowas:
"select * from xxx where aaa like '%%%s%%' or bbb like '%%%s%%'" % (a, b)
Dies funktioniert, aber irgendwie will es bei mir nicht mit dem ?-Platzhalter...
Schöne Grüße, Matthias
_______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de
Diesbezüglich habe ich auch noch schnell eine Frage... kann man den ?-Operator auch an der Stelle für den Tabellennamen benutzen? Denn dort gelingt mir nur die String Verkettung, was aber zu leichter SQL Injection führen kann. Freundliche Grüße Micha

Diesbezüglich habe ich auch noch schnell eine Frage... kann man den ?-Operator auch an der Stelle für den Tabellennamen benutzen? Denn dort gelingt mir nur die String Verkettung, was aber zu leichter SQL Injection führen kann.
Nein, kann man nicht. Das ist nur fuer Parameter. Diez

Hallo Michael, On 2008-06-18 09:27, Michael Perscheid wrote:
Diesbezüglich habe ich auch noch schnell eine Frage... kann man den ?-Operator auch an der Stelle für den Tabellennamen benutzen? Denn dort gelingt mir nur die String Verkettung, was aber zu leichter SQL Injection führen kann.
du kannst den Tabellennamen per %-Formatierung in den SQL-String einsetzen, bevor du ihn in der execute-Methode verwendest. Aber: Jeweils bevor du das tust, vergleiche den Tabellennamen mit einer Whitelist erlaubter Namen und führe das Query nur aus, wenn der einzusetzende Tabellen- name in der Liste enthalten ist. Das ist zwar nicht so bequem wie das Einsetzen der Parameter, aber vielleicht ein akzeptabler Kompromiss: if table_name in table_whitelist: query = query_template % table_name conn.execute(query, parameters) else: # deny, perhaps raise an exception ... Möglicherweise kommen nur einige wenige Tabellen in Frage, dann kannst du die Liste fest vorgeben. Wo diese Liste stehen sollte, hängt von der Struktur deiner Software ab. _Eventuell_ kann es sich sogar anbieten, die Liste in einer Datenbanktabelle zu speichern. Sonst kannst du die Liste u. U. auch automatisch erzeugen, wobei du jedoch sehr aufpassen musst, nur die erlaubten Tabellen zu erfassen. Hast du mehrere Whitelists für solche Querys, pass auf, dass du immer die richtige Whitelist für das entsprechende Query verwendest. :) Ein denkbarer Ansatz ist auch, den gegebenen Tabellennamen mit einem Muster zu vergleichen, ungefähr so: match = re.search("^[A-Za-z_]+$, table_name) if match: query = query_template % table_name conn.execute(query, parameters) else: # deny, perhaps raise an exception ... Das ist allerdings meiner Meinung nach heikel, unter anderem, weil damit zu viele unerwünschte Tabellen möglich bleiben, zum Beispiel Systemtabellen der Datenbank. Es verhindert aber zumindest typische Attacken mit SQL-Fragmenten. Viele Grüße Stefan
participants (5)
-
Diez B. Roggisch
-
Matthias Huening
-
Michael Perscheid
-
Sebastian Wiesner
-
Stefan Schwarzer