MySQL querys escapen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Volvic
User
Beiträge: 30
Registriert: Donnerstag 14. Juni 2007, 05:18

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?
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.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

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.
Volvic
User
Beiträge: 30
Registriert: Donnerstag 14. Juni 2007, 05:18

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.
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.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

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!
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Zu dem Thema haben wir eine wunderbare Wiki Seite: [wiki]Parametrisierte SQL-Queries[/wiki]

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

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.
Volvic
User
Beiträge: 30
Registriert: Donnerstag 14. Juni 2007, 05:18

schöne wiki seite, danke :)
Volvic
User
Beiträge: 30
Registriert: Donnerstag 14. Juni 2007, 05:18

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))
Antworten