2017-05-08 5 views
1

I Pyodbc Cursor ausführen, den richtigen Weg zu verwenden, versuchen Injection-Angriffe zu verhindern, wie hier vorgeschlagen: what does ? mean in python pyodbc modulePyodbc SQL-Code ausführen

Mein Code ist wie folgt:

query = """\ 
SELECT 
    ?,count(*) 
FROM 
    ? 
WHERE 
    ?=? 
""", ('date', 'myTable', 'date', '2017-05-08') 
cursor.execute(query) 

Und ich bekomme eine Fehler:

TypeError: The first argument to execute must be a string or unicode query. 

Für die richtige Antwort würde ich möchte:

  1. Behalten Sie das Fragezeichen-Format, um SQL-Injection-Angriffe zu vermeiden
  2. Halten Sie das Triple-Anführungszeichen-Format, damit ich lange SQL-Abfragen schreiben kann und die Codelesbarkeit nicht verliere.

Gibt es einen Weg, dies zu erreichen? Ich weiß, ich könnte """ %s """ %('table') Format-Typ verwenden, aber das schlägt den Zweck dieser Frage.

+0

Ok, Ihre Bearbeitung kam zur gleichen Zeit wie mein Kommentar. Woher bekommst du 'myTable' und' date' Strings? Es ist unwahrscheinlich, dass diese von Freetext irgendwo in deinem Setup kommen würden? Ein _value_ für das Datum könnte von einem Benutzer eingegeben werden, aber würden sie angeben, dass es in die "Datum" -Spalte Ihrer Tabelle geschrieben wird? Mit anderen Worten, könnten Sie durch die Formatierung des Tabellennamens und der Spaltennamen anfällig für SQL-Injection sein? – roganjosh

Antwort

3

Sie haben 2 Ausgaben:

  1. query ist ein Tupel. Die Art und Weise eine parametrisierte Abfrage auszuführen ist wie folgt:

    query = """SELECT ?,count(*) 
          FROM ? 
          WHERE ?=? """ 
    args = ('date', 'myTable', 'date', '2017-05-08') 
    cursor.execute(query, args) 
    

    Sie query mit * passieren könnte. Dies würde erweitern query in einen String und ein Tupel, das ist das, was execute erwartet:

    cursor.execute(*query) # 'query' here is defined as it is in your example 
    
  2. Aber das wird nicht funktionieren. Sie können die parametrisierte Abfrage nicht verwenden, um Parameter in den SELECT- und FROM-Klauseln zu verwenden. Sie können in der where-Klausel auch keine Parameter für den Spaltennamen verwenden.

Sie (in der Regel) müssen nicht über SQL-Injection-Sorgen, wenn der Wert nicht durch den Benutzer eingegeben wird (oder wenn der Benutzer kann es nicht in irgendeiner Weise ändern).