addslashes() in python?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Daveron

Gibt es eine Funktion, die mir in einem String die Sonderzeichen so auskommentiert, das ich diesen sauber in eine SQL DB schreiben kann?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Daveron

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

Damit nutzt du nicht die SQL-Escape Funktion der API! Was du machst, ist eine normale String-Operation, ohne irgendweine Escape Funtkion! Es muß beim .execute() gemacht werden!

Schau dir den anderen Thread an.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Daveron

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
Benutzeravatar
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 ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
ProgChild
User
Beiträge: 210
Registriert: Samstag 9. April 2005, 10:58
Kontaktdaten:

Daveron 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
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 lassen :!:

Ein kleines Beispiel:

Code: Alles auswählen

query = "DELETE FROM address WHERE ID=%s"
data = ( id, )

cursor.execute( query, data )
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

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.

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"
      })
Sorry, falls das zu lang sein sollte, oder als OT empfunden wird!

Henning
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Ich kann natürlich nicht garantieren, dass das Quoting korrekt ist, aber alle meine Versuche, da eine SQL-Injection durchzukriegen sind bis jetzt gescheitert :-)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

henning hat geschrieben:Sorry, falls das zu lang sein sollte, oder als OT empfunden wird!
Zu lang für das Forum ist es nicht, aber zulang für das Problem ;)

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

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

jens hat geschrieben: Also wenn die SQL-Anbindung schon ein Escaping besitzt, warum das nicht einfach benutzten???
Ganz einfach deswegen, weil ich auch Spalten- und Tabellennamen über unsichere Kanäle gechickt/empfangen habe und die dementsprechend auch gequotet haben wollte.

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.
Daveron

jo genau danach hatte ich gesucht. läuft wunderbar ;P
Antworten