addslashes() in python?
Gibt es eine Funktion, die mir in einem String die Sonderzeichen so auskommentiert, das ich diesen sauber in eine SQL DB schreiben kann?
ich escape bereits mit %s:
sql_query = "INSERT INTO test (text) VALUES ('%s') " % inhalt
ansicht klappt das ganz gut, doch leider machen mir hochkommas probleme.
sql_query = "INSERT INTO test (text) VALUES ('%s') " % inhalt
ansicht klappt das ganz gut, doch leider machen mir hochkommas probleme.
hab mir jetzt ne Funktion mit reg exp gebaut, die mir alle Sonderzeichen mit einem '\' für das SQL Statement auskommentiert.
Ich kann leider nicht einfach so die klasse für den zugriff auf die Datenbank verändern, da noch andere damit arbeiten ;P
Ich kann leider nicht einfach so die klasse für den zugriff auf die Datenbank verändern, da noch andere damit arbeiten ;P
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Das ist allerdings keine gute Idee! SQL-Injections sind damit nicht ausgeschlossen, glaub ich...
Es gibt, zumindest bei der mySQLdb auch eine spezielle Funktion die das erledigen kann... Ich weiß jetzt nur nicht, wie die heißt... Da hilft bestimmt ein help() weiter
Es gibt, zumindest bei der mySQLdb auch eine spezielle Funktion die das erledigen kann... Ich weiß jetzt nur nicht, wie die heißt... Da hilft bestimmt ein help() weiter

Warum schreibst du dir ne Funktion, wenn dir Jens schon ne komplette Lösung anbietet? *kopfschüttel* Du solltest unter allen Umständen die Escape Sequenzen von SQL einfügen lassenDaveron hat geschrieben:hab mir jetzt ne Funktion mit reg exp gebaut, die mir alle Sonderzeichen mit einem '\' für das SQL Statement auskommentiert.
Ich kann leider nicht einfach so die klasse für den zugriff auf die Datenbank verändern, da noch andere damit arbeiten ;P

Ein kleines Beispiel:
Code: Alles auswählen
query = "DELETE FROM address WHERE ID=%s"
data = ( id, )
cursor.execute( query, data )
Ich habe den Thread hier nur angelesen, daher keine Ahnung, ob das Problem nicht schon an sich gelöst wurde, aber ich hab mich vor kurzem auch ein bisschen damit befasst und mal eine Funktion geschrieben die potentiell bösartige strings je nachdem ob sie ein Wert oder ein "Key" (also Spalte oder Tabellenname) sein sollen, quotet.
Sorry, falls das zu lang sein sollte, oder als OT empfunden wird!
Henning
Code: Alles auswählen
#!/usr/bin/python
"""
save_sql.py
Author: Henning Hasemann
A little module ensuring that userdata wont
hurt sql-strings, quoting tablenames, column names and
values correctly.
Note 1: You are allowed to just provide one dictionary instead
of two. In this case, it will be used for both, keys and values.
Note 2: Always use %(Kname)s / %(Vname)s, (pronouncing the last s),
because all values are internally converted into strings.
(i.e. it makes no sense to use %(Vname)d, as this simply wont work)
Example:
import MySQLdb
from save_sql import mksql
conn = MySQLdb.connect(db="MyDatabase", user="MyUser", paswd="MyPW", host="localhost")
curs = conn.cursor()
query = mksql("INSERT INTO %(Ktab)s (`name`, `surname`, %(Kcol3)s, `count`) VALUES (%(Vname)s, %(Vsur)s, 'X', %(Vcnt)s)",
{"tab": "MyTable", "col3": "Some` really; unsafe stuff\\"},
{"name": "'; DELETE", "sur": "even' unsafer`blorg", "cnt": 500})
curs.execute(query)
curs.close()
conn.close()
"""
escape_keys = ("\\", "`", ";")
escape_values = ("\\", "'", ";")
def mksql(string, keys = False, values = False, **kwars):
"""Fills string. %(Ksome_name)s will be subsituted
with the key-like (think of columns and table names) quoted
value of keys["some_name"], while
%(Vsomething)s will be substituted by the value-like quoted
value of values["something"] or keys["something"] if values
is not defined.
Note that this function raises the usual KeyError when
a value requested is not found in the dict."""
if not keys:
keys = kwars
if not values:
values = keys
d = {}
for k, v in keys.items():
d["k" + k] = to_key(str(v))
d["K" + k] = "`" + to_key(str(v)) + "`"
# R is for "raw". Please use this with extreme
# caution, since raw data is not preprocessed at all.
# Whatever you take as raw data should
# - not depend on user accesiable input
# or
# - be checked very very carefully!
d["R" + k] = str(v)
for k, v in values.items():
d["v" + k] = to_value(str(v))
d["V" + k] = "'" + to_value(str(v)) + "'"
return string % d
def to_key(v):
"""Converts an unstrusted sql-key into a save one.
Note that this DOES NOT add the ` - signs on the left
and the right, but please dont provide them in the paramter,
because there they will be quoted.
You'll have to add them yourself later!
This function will be called by mksql."""
for r in escape_keys:
v = v.replace(r, "\\" + r)
return v
def to_value(v):
"""Converts an unstrusted sql-value into a save one.
Note that this DOES NOT add the ' - signs on the left
and the right, but please dont provide them in the paramter,
because there they will be quoted.
You'll have to add them yourself later!
This function will be called by mksql."""
for r in escape_values:
v = v.replace(r, "\\" + r)
return v
if __name__ == "__main__":
# short mixed form:
# sql-string values and keys via keywords
print mksql("SELECT * FROM %(Ktab)s WHERE %(Kkey)s=%(Vval)s",
tab="tabelle", key="schlüssel", val="Wert")
# long mixed form:
# sql-string, values and keys in one dict
print mksql("SELECT * FROM %(Ktab)s WHERE %(Kkey)s=%(Vval)s",
{
"tab": "tabelle",
"key": "schlüssel",
"val": "Wert"
})
# long splitted form:
# sql-string, dict of keys, dict of values
print mksql("SELECT * FROM %(Ktab)s WHERE %(Kkey)s=%(Vval)s",
{
"tab": "tabelle",
"key": "schlüssel",
},
{
"val": "Wert"
})
Henning
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Zu lang für das Forum ist es nicht, aber zulang für das Problemhenning hat geschrieben:Sorry, falls das zu lang sein sollte, oder als OT empfunden wird!

Also wenn die SQL-Anbindung schon ein Escaping besitzt, warum das nicht einfach benutzten???
Schau mal mit "help(MySQLdb)" nach dem Stichwort "escape": Mir scheint das MySQLdb.escape_string() genau das macht, was ihr wollt...
Aber wie ProgChild schon geschrieben hat: Du solltest unter allen Umständen die Escape Sequenzen von SQL einfügen lassen
Ganz einfach deswegen, weil ich auch Spalten- und Tabellennamen über unsichere Kanäle gechickt/empfangen habe und die dementsprechend auch gequotet haben wollte.jens hat geschrieben: Also wenn die SQL-Anbindung schon ein Escaping besitzt, warum das nicht einfach benutzten???
In der Doku zu MySQLdb wurde explizit erwähnt, dass man das Quoting, dass die bieten NUR für Werte verwenden soll.
Und dann teilweise was eigenes und teilweise das von MySQLdb zu nutzen war mir zu unübersichtlich, da fand ichs schöner, eine Funktion zu haben, die das alles erledigt.
Aber wenn man nur Werte quoten will geb ich dir natürlich Recht, reicht das Ding von der MySQLdb auch.
Aber vielleicht passt der Post ja in die Codesnippets-Ecke.