Seite 1 von 1

MySQL querys escapen

Verfasst: Samstag 7. Juli 2007, 01:40
von Volvic
hallo :)

ich suche funktionen um meine MySQL querys zu schützen, da nachdem ich http://www.devshed.com/c/a/MySQL/MySQL- ... -Overview/ gelesen habe stutzig geworden bin. in php gibt es nun extra funktionen dafür, wie sieht mit der python lib oder evtl sogar in Paste aus?
ich wäre nicht abgeneigt soetwas selbst zu bauen, im gegenteil es wäre mir sogar lieber. allerdings wie sollte man dann vorgehen, einfach SQL befehle spricht SELECT etc. escapen, wobei ich denke das das nicht reichen würde?

Verfasst: Samstag 7. Juli 2007, 08:07
von BlackJack
Diese Funktionalität ist in der DB 2.0 API definiert. Die `execute()`-Methode macht das. Schau Dir einfach mal die Doku dazu und das zweite Argument an.

Verfasst: Samstag 7. Juli 2007, 11:16
von Y0Gi
Alleine vorausgesetztes Auto-Escaping ist in meinen Augen schon fast ein Killer-Argument gegen die Nutzung von PHP. Man sehe sich nur mal an, wieviele SQL-Injection-Exploits (Tipp: sehr viele!) entdeckt werden und täglich aufmerksame (weil nach Updates sehende) Betreiber von WordPress, phpBB und Konsorten um den Verstand bringen.

Verfasst: Samstag 7. Juli 2007, 19:30
von Volvic
das scheint das passende zu sein, in der DB 2.0 API wird es allerdings nur für die SQLite lib erklärt. aus der MySQLdb api werde ich nicht schlau:
| execute(self, query, args=None)
| Execute a query.
|
| query -- string, query to execute on server
| args -- optional sequence or mapping, parameters to use with query.
|
| Note: If args is a sequence, then %s must be used as the
| parameter placeholder in the query. If a mapping is used,
| %(key)s must be used as the placeholder.
|
| Returns long integer rows affected, if any
mein problem ist das ich noch nie etwas mit mapping zu tuen habe und mit sequenzen ebensowenig (habe sequenzen nie gebraucht bisher). was sequezen sind verstehe ich nur bei strings, allerdings nicht in dem zusammenhang mit dieser excute() funktion.

Verfasst: Samstag 7. Juli 2007, 21:01
von BlackJack
Die DB 2.0 API ist unabhängig von konkreten Datenbanken. Die gilt auch für das MySQLdb-Modul.

"Mappings" sind Abbildungen von Schlüsseln auf Werte, also zum Beispiel Dictionaries und Sequenzen sind Objekte die einen Indexzugriff erlauben, also zum Beispiel Listen oder Tupel. Solltest Du also beides kennen.

Verfasst: Sonntag 8. Juli 2007, 10:15
von Y0Gi
Beispiel:

Code: Alles auswählen

id = 123
cursor.execute('''
    SELECT id, name, age
    FROM people
    WHERE id = %s
    ''', (123,))
Hinweis 1: Der zweite Parameter, `args`, muss eine Sequenz sein. Bei nur einem Wert kann man also eine Liste `[123]` oder ein 1-Tupel `(123,)` (man beachte das Komma!) verwenden - `(123)` wäre dagegen verkehrt.

Hinweis 2: *Ganz* vorsichtig sein, dass man ein Komma benutzt, um die Argumente zu trennen! Die Platzhalter-Syntax ist unterschiedlich und kann $1, %s, ? oder anders lauten und ist (leider) von DB-Modul zu DB-Modul unterschiedlich. Sofern aber %s benutzt wird, könnte man anstelle des Kommas den %-Operator verwenden und erhält bei bestimmten Werten dasselbe Ergebnis. Hierbei wird allerdings von Python der String zusammengesetzt und dann als erster Parameter übergeben. Das Autoescaping ist damit aber erfolgreich außer Kraft gesetzt worden!

Verfasst: Montag 9. Juli 2007, 07:59
von jens
Zu dem Thema haben wir eine wunderbare Wiki Seite: [wiki]Parametrisierte SQL-Queries[/wiki]

Verfasst: Montag 9. Juli 2007, 11:09
von Y0Gi
Ach Jens, was wären wir ohne deine Wiki-Hinweise ;)

Ich habe mir mal erlaubt, auf der Seite die SQL-Statements umzubrechen, damit sie leichter erfassbar sind und man nicht horizontal scrollen muss.

Verfasst: Montag 9. Juli 2007, 16:01
von Volvic
schöne wiki seite, danke :)

Verfasst: Dienstag 17. Juli 2007, 12:18
von Volvic
ich hätte noch eine kleine frage bezüglich des escapen:

Code: Alles auswählen

def doSQL(query, *args, **kwargs):
	cur = db1.cursor()
	cur.execute(query, (*args, **kwargs))
	cur.close()
	return result
ich ich benötige öfters eine unbestimmte anzahl an argumenten, ist diese lösung mit kwargs so korrekt?

oder müßte ich es etwa so machen:

Code: Alles auswählen

cur.execute(query, (*args, **kwargs))
und die funktion so aufrufen:

Code: Alles auswählen

doSQL('mein query...', (var1, var2, var3))