SQL-Injection ist eine der häufigsten Netzwerkangriffsmethoden. Sie nutzt nicht den Fehler des Betriebssystems, um den Angriff durchzuführen, sondern zielt auf die Nachlässigkeit des Programmierers ab. Durch SQL-Anweisungen kann er sich ohne Konto anmelden sogar die Datenbank manipulieren. Der folgende Artikel stellt Ihnen hauptsächlich die Methoden zur Verhinderung der SQL-Injection in Python vor. Freunde in Not können sich darauf beziehen.
Vorwort
Jeder sollte wissen, dass die größte Web-Schwachstelle mittlerweile SQL ist, egal welche Sprache für die Web-Back-End-Entwicklung verwendet wird , Solange Sie eine relationale Datenbank verwenden, kann es zu SQL-Injection-Angriffen kommen. Wie sieht die SQL-Injection während der Python-Webentwicklung aus und wie lässt sich dieses Problem lösen?
Natürlich möchte ich nicht diskutieren, wie andere Sprachen die SQL-Injektion vermeiden. Es gibt verschiedene Möglichkeiten, die Injektion in PHP zu verhindern (Anmerkung des Bloggers: Es gilt als die großartigste Sprache der Welt ) im Internet, einschließlich Python. Die Methoden sind tatsächlich ähnlich, daher gebe ich Ihnen hier ein Beispiel.
Ursache
Die häufigste Ursache der Schwachstelle ist das String-Splicing. Natürlich funktioniert SQL-Injection nicht ist nur ein Fall des Spleißens, aber es gibt viele andere Arten wie Wide-Byte-Injection, Sonderzeichen Escape usw. Hier werden wir über das häufigste String-Spleißen sprechen, das auch der häufigste Fehler ist Nachwuchsprogrammierer.
Zuerst definieren wir eine Klasse, um die Operation von MySQL zu verarbeiten
class Database: aurl = '127.0.0.1' user = 'root' password = 'root' db = 'testdb' charset = 'utf8' def init(self): self.connection = MySQLdb.connect(self.aurl, self.user, self.password, self.db, charset=self.charset) self.cursor = self.connection.cursor() def insert(self, query): try: self.cursor.execute(query) self.connection.commit() except Exception, e: print e self.connection.rollback() def query(self, query): cursor = self.connection.cursor(MySQLdb.cursors.DictCursor) cursor.execute(query) return cursor.fetchall() def del(self): self.connection.close()
Dieser Code wurde in vielen meiner vorherigen Skripte gesehen, die Python-Operationen beinhalteten Ich werde diese Klasse in die Skripte der MySQL-Datenbank schreiben. Gibt es also ein Problem mit dieser Klasse?
Die Antwort lautet: Ja!
Diese Klasse ist fehlerhaft und kann leicht eine SQL-Injection verursachen. Lassen Sie uns darüber sprechen, warum SQL-Injection auftritt.
Um die Authentizität des Problems zu überprüfen, finden Sie hier eine Methode zum Aufrufen der Methode in der obigen Klasse. Wenn ein Fehler auftritt, wird direkt eine Ausnahme ausgelöst.
def test_query(articleurl): mysql = Database() try: querySql = "SELECT * FROM `article` WHERE url='" + articleurl + "'" chanels = mysql.query(querySql) return chanels except Exception, e: print e
Diese Methode ist sehr einfach. Eine der häufigsten select-Abfragen-Anweisungen verwendet auch das einfachste String-Splicing, um eine SQL-Anweisung zu bilden. Es ist offensichtlich, dass der Parameter „articleurl“ übergeben wird ist kontrollierbar. Wenn Sie Injektionstests durchführen möchten, müssen Sie nach dem Wert von ArticleURL nur einfache Anführungszeichen hinzufügen, um einen SQL-Injection-Test durchzuführen. Führen Sie das Skript aus und sehen Sie, was die Ergebnisse sind sind
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''t.tips''' at line 1")
Die Testparameter, die ich hier übergeben habe, sind
t.tips'
Das Folgende ist eine weitere Situation, die zur Injektion führt
def test_query(articleurl): mysql = Database() try: querySql = ("SELECT * FROM `article` WHERE url='%s'" % articleurl) chanels = mysql.query(querySql) return chanels except Exception, e: print e
Diese Methode verwendet keine direkte Zeichenfolgenverkettung, sondern verwendet %s, um die zu übergebenden Parameter zu ersetzen. Sieht es nicht sehr nach vorkompiliertem SQL aus? Kann diese Schreibweise die SQL-Injection verhindern? Nach einem Test wissen Sie, dass das folgende Echo
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''t.tips''' at line 1")
mit dem obigen Testergebnis übereinstimmt. Daher ist diese Methode nicht möglich und diese Methode ist keine vorkompilierte SQL-Anweisung Was muss getan werden, um die SQL-Injektion zu verhindern? Wolltuch?
Lösung
Zwei Lösungen
1> die Eingabeparameter
2> Verwenden Sie die Methode, die mit dem MySQLdb-Modul geliefert wird.
Die erste Lösung ist tatsächlich in vielen PHP-Anti-Injection-Methoden zu finden. Sie führt eine Sonderzeichenmanipulation an Sonderzeichen durch oder filtern.
Die zweite Möglichkeit besteht darin, interne Methoden zu verwenden, ähnlich wie PDO in PHP. Hier können Sie einfach die obige Datenbankklasse ändern.
Geänderter Code
class Database: aurl = '127.0.0.1' user = 'root' password = 'root' db = 'testdb' charset = 'utf8' def init(self): self.connection = MySQLdb.connect(self.aurl, self.user, self.password, self.db, charset=self.charset) self.cursor = self.connection.cursor() def insert(self, query, params): try: self.cursor.execute(query, params) self.connection.commit() except Exception, e: print e self.connection.rollback() def query(self, query, params): cursor = self.connection.cursor(MySQLdb.cursors.DictCursor) cursor.execute(query, params) return cursor.fetchall() def del(self): self.connection.close()
Hier werden bei der Ausführung zwei Parameter übergeben. Der erste ist die parametrisierte SQL-Anweisung und der zweite ist der entsprechende tatsächliche Parameterwert, die -Funktion verarbeitet den eingehenden Parameterwert entsprechend, um die SQL-Injection zu verhindern. Die tatsächlich verwendete Methode ist wie folgt:
preUpdateSql = "UPDATE `article` SET title=%s,date=%s,mainbody=%s WHERE id=%s" mysql.insert(preUpdateSql, [title, date, content, aid])
Auf diese Weise können Sie die SQL-Injection verhindern, nachdem das MySQLdb-Modul intern eine Liste übergeben hat Serialisieren Sie die Liste in ein Tupel und führen Sie dann die Escape-Operation aus.
[Verwandte Empfehlungen]
1. Python kostenloses Video-Tutorial
2. Python-Grundlagen-Einführungs-Tutorial
3. Geek Academy Python-Video-Tutorial
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Python-Methoden zur Verhinderung von SQL-Injection. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!