richtige Verwendung von Platzhaltern - best practise

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
RichardeRicharde
User
Beiträge: 16
Registriert: Montag 29. November 2021, 14:37

Hallo Zusammen,
in der Hoffnung nicht gesteinigt sondern erleuchtet zu werden wende ich mich mal wieder an die Experten hier.

In verschiedenen Tutorials wird immer wieder darauf hingewiesen das man sauber Programmieren soll um SQL-Injections zu verhindern.

Nun sind manche Tuturials schon über 12..14 Jahre alt und ich weiß nicht ob deren Inhalt noch aktuell bzw. State of the Art ist und manche Tutrials sind sicherlich auch fachlich nicht ganz korrekt.

Außerdem habe ich irgendwo gelesen das Methode XY gegen die "meisten" Arten von SQL Injections hilft - diese Aussage verunsichert einen als Beginner noch mehr.

Daher geht die Frage hier an die alten Hasen:
Welche Methoden von Dynamischen SQL Statements gibt es und sind alle gleich sicher? Welche sind eure Präferierten und weiß jemand ob es sprachliche Updates in den letzten 10 Jahren gab?

Außerdem sehe ich auch des Öfteren sowas:

Code: Alles auswählen

sql = '''select spalte1, spalte2
from mytable;'''

cursor.execute(sql)
Aber dort kann ich doch erst recht jeden möglichen (Schad)Code einfügen?

Ich hoffe Ihr habt Verständnis, ich bin durch viel lesen der letzten Tage an diesem Punkt nun eher verunsichert auf das falsche Pferd zu setzen, würde es aber gern richtig machen und im besten Falle auch verstehen warum (Wobei mir das Grundprinzip ja klar ist)

Vielen Dank für eure Zeit und Mühe
Richarde
Benutzeravatar
sparrow
User
Beiträge: 3329
Registriert: Freitag 17. April 2009, 10:28

Wie kommst du denn darauf, dass du in das von dir gezeigte Beispiel geeignet ist, in irgend einer Weise Schadcode auszuführen?

Code dagegen stabil zu halten ist recht einfach:
Entweder man verwendet eh schon ein ORM, die nehmen einen das ab.
Wenn man direkt SQL spricht, dann die Platzhalter verwenden, die das entprechende Modul vorgibt.
Und was du unter "dynamischen" Abfragen verstehst weiß ich nicht. Wichtig ist: In einer Abfrage im im Code ist alles statisch, bis auf die Werte. Insbesondere die Feldnamen, falls du das mit "dynamisch" meinst. Und die Werte werden durch Platzhalter übergeben. Wie genau die in der SQL-Abfrage zu bezeichnen sind, steht in dem entsprechenden Modul. Und in der Regel werden sie als Tupel als zweites Argument an die Abfrage übergeben.
RichardeRicharde
User
Beiträge: 16
Registriert: Montag 29. November 2021, 14:37

Vielen Dank für Deine Antwort.
sparrow hat geschrieben: Mittwoch 19. Januar 2022, 12:10 Wie kommst du denn darauf, dass du in das von dir gezeigte Beispiel geeignet ist, in irgend einer Weise Schadcode auszuführen?
Wenn zur Laufzeit der Inhalt von sql geändert wird, kann ich doch damit jeden Befehl an die DB absetzen?
Ich dachte durch diverse Platzhalter und den Befehlsteil als Coding ist dies nicht mehr möglich.
sparrow hat geschrieben: Mittwoch 19. Januar 2022, 12:10 Code dagegen stabil zu halten ist recht einfach:
Entweder man verwendet eh schon ein ORM, die nehmen einen das ab.
Kannte ich noch garnicht als Neuling, musste erstmal object-relational mapper googlen. Dies sind alles Erweiterungen - kann jemand eine oder mehrere Empfehlen?
sparrow hat geschrieben: Mittwoch 19. Januar 2022, 12:10 Wenn man direkt SQL spricht, dann die Platzhalter verwenden, die das entprechende Modul vorgibt.
Und was du unter "dynamischen" Abfragen verstehst weiß ich nicht. Wichtig ist: In einer Abfrage im im Code ist alles statisch, bis auf die Werte. Insbesondere die Feldnamen, falls du das mit "dynamisch" meinst. Und die Werte werden durch Platzhalter übergeben. Wie genau die in der SQL-Abfrage zu bezeichnen sind, steht in dem entsprechenden Modul. Und in der Regel werden sie als Tupel als zweites Argument an die Abfrage übergeben.
Was verstehst Du unter Modul in dem Kontext? Meinst Du meine Variablen aus der Methode die ich als Wrapper um das SQL-Statement baue?
Mit Dynamisch habe ich mich schlecht ausgedrückt, ich meinte natürlich nur Werte Dynamisch übergeben zum Beispiel Daten für ein INSERT oder für eine Werte für eine WHERE Bedingung.
__deets__
User
Beiträge: 11950
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie sollte denn zur Laufzeit der Inhalt von sql geaendert werden? Es geht bei SQL-Injection um Nutzereingaben, die als Parameter (zB email/username eines logins) in das SQL muessen. Niemand kann dadurch einfach beliebige Variablen in deinem Programm aendern. Wenn das ginge, ist SQL-injection das geringste deiner Probleme.

Und Modul meint in diesem Zusammenhang den SQL API connector, als MySQL, sqlite, etc. Das ist ja ein Modul, das du importierst.
Benutzeravatar
sparrow
User
Beiträge: 3329
Registriert: Freitag 17. April 2009, 10:28

Wie soll denn zur Laufzeit der Inhalt von SQL geändert werden? Es sei denn du erlaubst es dem Anwender der Software explizit.

ORM unter Python allgemein: SQLAlchemy.
Django bringt z. B. sein eigenes ORM mit.

Zum Modul: Du musst ja mit irgend einem Modul mit der Datenbank sprechen. Und dessen Dokumentation sollte dir auch sagen, wie man die Platzhalter verwendet.

sqlite3:

Code: Alles auswählen

cur.execute("insert into lang values (?, ?)", ("C", 1972))
psycopg für postgres-Anbindung:

Code: Alles auswählen

>>> cur.execute("""
...     INSERT INTO some_table (an_int, a_date, a_string)
...     VALUES (%s, %s, %s);
...     """,
...     (10, datetime.date(2005, 11, 18), "O'Reilly"))
Deshalb ist es sinnvoll, sich mit ORM auseinander zu setzen.
RichardeRicharde
User
Beiträge: 16
Registriert: Montag 29. November 2021, 14:37

Vielen Dank euch beiden, bisher hatte ich immer nur sqlite3 importiert.

Werde mich mal mit sqlalchemy auseinandersetzen.

Ich entnehme euren Antworten und meinen kurzen Google-Exkusen zum Thema das ORM Vorteile hat, weil er einem Gewisse SQL Anweisungen schon gescheit wrapped und auch der Zugriff auf Variablen im Zusammenhang mit Daten aus der DB oder für die DB einfacher darstellt und sich zu dem SQL-Injections schon durch den ORM verhindert werden.
Ich hoffe ich habe das richtig zusammen gefasst und werde mich dann mal mit der Seite https://docs.sqlalchemy.org/ beschäftigen, außer Ihr habt noch andere oder weitere Vorschläge für mich.

Nutzt Ihr immer ORM oder in der Regel immer ORM?
Benutzeravatar
__blackjack__
User
Beiträge: 10254
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Es gibt noch einen Zwischenschritt den man gehen kann zwischen konkreten Datenbankmodulen und ORM und das wäre auch SQLAlchemy, denn den ORM-Teil davon muss man nicht zwingend benutzen. Das Package macht IMHO auch schon Sinn wenn man ”nur” eine einheitlichere API über verschiedene DBMS verwenden will, und Abfragen dynamisch auf-/zusammenbaut und dabei nicht auf irgendwelches wackeliges Zeichenkettengefrickel mit Teilabfragen setzen möchte. Und einen Verbindungspool kann man auch ohne ORM benutzen.

Ich nutze in der Regel immer SQLAlchemy, auch ohne ORM in Fällen, in denen das keinen Sinn macht.
“Ich bin für die Todesstrafe. Wer schreckliche Dinge getan hat, muss eine angemessene Strafe bekommen. So lernt er seine Lektion für das nächste Mal.”
— Britney Spears, Interview in der französischen Zeitung Libération, 2. April 2002
RichardeRicharde
User
Beiträge: 16
Registriert: Montag 29. November 2021, 14:37

__blackjack__ hat geschrieben: Mittwoch 19. Januar 2022, 16:57 Ich nutze in der Regel immer SQLAlchemy, auch ohne ORM in Fällen, in denen das keinen Sinn macht.
Vielen Dank - jetzt muss ich mir "nur" noch anschauen in welchen Fällen dies Sinn macht und in welchen nicht.
Werde für meine nächsten Gehversuche aber SQLAlchemy verwenden.

Außerdem hab ich heute noch richtig Lust auf UNIT-Tests bekommen und möchte mir noch PyTest ansehen.

Zu lernen gibt es erstmal genug :-)

Ich Danke euch allen nochmals
DasIch
User
Beiträge: 2709
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

RichardeRicharde hat geschrieben: Mittwoch 19. Januar 2022, 13:26 Nutzt Ihr immer ORM oder in der Regel immer ORM?
ORMs bilden SQL quasi nie vollständig ab, bei komplexen Queries ist SQL selbst schreiben manchmal leichter und verständlicher und in seltenen Fällen möchte man vielleicht einfach einen anderen SQL Query haben als das ORM generiert z.B. um die Datenbank zu einem anderen Query Plan zu überreden.

Aus diesen Gründen ist "immer ORM" in der Praxis ziemlich selten es sei den du hast wirklich nur eine recht einfache Anwendung. Die meiste Zeit, vielleicht sogar fast immer, ist es aber sehr praktisch ein ORM zu haben, vor allem wenn man Queries dynamisch verändern will was bei Bedingungen in der where clause und ähnlichen Dingen sehr häufig vorkommt. Insofern ist es schon empfehlenswert ein ORM zu nutzen.
Antworten