ホームページ >バックエンド開発 >Python チュートリアル >Pythonを使用してSQLインジェクションを防ぐ方法
Web の最大の脆弱性は SQL に他なりません。Web バックエンド開発にどの言語が使用されていても、リレーショナル データベース が使用されている限り、SQL インジェクション攻撃に遭遇する可能性があります。では、SQL インジェクションは Python Web 開発のプロセスでどのように発生し、この問題をどのように解決するのでしょうか?
もちろん、他の言語が SQL インジェクションを回避する方法については議論したくありません。PHP でのインジェクションを防ぐ方法は、実際にはインターネット上にあります。ここでは例を示します。
この脆弱性の最も一般的な理由は文字列スプライシングです。もちろん、SQLインジェクションは単なるスプライシングのケースではなく、ワイドバイトインジェクション、特殊文字エスケープなど、他にも多くの種類があります。 , ここでは、最も一般的な文字列の連結について説明します。これは、ジュニア プログラマーにとって最もよくある間違いでもあります。
まず、mysql
class Database: hostname = '127.0.0.1' user = 'root' password = 'root' db = 'pythontab' charset = 'utf8' def init(self): self.connection = MySQLdb.connect(self.hostname, 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()
の操作を処理するクラスを定義しますこのクラスに問題はありますか?
答えは「はい」です。
このクラスには欠陥があり、SQL インジェクションが簡単に発生する可能性があります。なぜ SQL インジェクションが発生するのかについて説明します。
問題の真偽を検証するために、上記のクラス内のメソッドを呼び出して、エラーが発生した場合に直接例外をスローする方法を示します。
def test_query(testUrl): mysql = Database() try: querySql = "SELECT * FROM `article` WHERE url='" + testUrl + "'" chanels = mysql.query(querySql) return chanels except Exception, e: print eこのメソッドは非常に単純です。最も一般的な select
(1064, " SQL 構文にエラーがあります。MariaDB サーバーのバージョンに対応するマニュアルを確認してください
正しい構文を確認してください。 エラー メッセージが表示されます。はよくあるエラーです。ここで渡します。入力されたテストパラメータはt.tips'
上記のメソッドを少し変更した後の別の状況です
def test_query(testUrl): mysql = Database() try: querySql = ("SELECT * FROM `article` WHERE url='%s'" % testUrl) chanels = mysql.query(querySql) return chanels except Exception, e: print e
このメソッドは直接使用しません。文字列のスプライシングですが、渡されるパラメータの代わりに %s を使用しますが、プリコンパイルされた SQL と非常によく似ていますか?この書き方でSQLインジェクションを防ぐことはできるのでしょうか?テストしてみるとわかります。応答は次のとおりです
(1064, "SQL 構文にエラーがあります。"t.tips 付近で使用する正しい構文については、MariaDB サーバーのバージョンに対応するマニュアルを確認してください。 ''' 行 1")
テスト結果は上記と同じであるため、この方法は実行可能ではありません。また、この方法はプリコンパイルされた SQL ステートメントではありません。では、SQL インジェクションを防ぐにはどうすればよいでしょうか?
解決策
2つの解決策
1>受信パラメータのエンコードとエスケープPDO
に似た内部メソッドを使用することです。ここでは、上記のデータベース クラスを単純に変更できます。
変更されたコード
class Database: hostname = '127.0.0.1' user = 'root' password = 'root' db = 'pythontab' charset = 'utf8' def init(self): self.connection = MySQLdb.connect(self.hostname, 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()
executeが実行されると、2つのパラメータが渡されます。1つ目はパラメータ化されたSQL文で、2つ目は対応する実際のパラメータ値です。関数は、受信したパラメータ値を内部的に処理します。 SQL インジェクションを防ぐために、実際に使用されるメソッドは次のとおりです
preUp
dateSql = "UPDATE `article` SET title=%s,date=%s,mainbody= % s WHERE id=%s"
mysql.insert(preUpdateSql, [title, date, content, aid])
以上がPythonを使用してSQLインジェクションを防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。