SQL インジェクションは、最も一般的なネットワーク攻撃手法の 1 つであり、攻撃を実行するためにオペレーティング システムのバグを使用するのではなく、SQL ステートメントを通じて、アカウントなしでログインしたり、改ざんしたりする可能性があります。データベースと一緒に。以下の記事ではPythonでSQLインジェクションを防ぐ方法を中心に紹介していますので、困っている方は参考にしてください。
はじめに
現在、Web の最大の脆弱性は SQL であることを誰もが知っているはずです。Web バックエンド開発にどの言語が使用されているかに関係なく、リレーショナル データベース を使用している限り、SQL に遭遇する可能性があります。注射攻撃の質問です。では、Python Web 開発中に SQL インジェクションはどのように発生し、この問題をどのように解決するのでしょうか?
もちろん、他の言語が SQL インジェクションを回避する方法についてここで議論するつもりはありません。PHP (ブロガー注: 世界で最も素晴らしい言語と言われています) ではインジェクションを防ぐためのさまざまな方法があります。インターネット。Python のメソッドも同様です。ここで例を示します。原因
この脆弱性の最も一般的な原因は、文字列スプライシングだけではなく、ワイドバイトインジェクション、特殊文字エスケープなども含まれます。多くの種類がありますが、ここでは最も一般的な文字列の連結について説明します。これは、若手プログラマーにとって最もよくある間違いでもあります。
まず、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()の操作を処理するクラスを定義します。このコードは、これまでのスクリプトの多くで見られましたが、このクラスを Python 操作
mysql データベース に関係するスクリプトに記述します。問題? 答えは次のとおりです。
。 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
このメソッドは非常に単純です。最も一般的な select
ステートメントの 1 つでは、最も単純な文字列連結を使用して SQL ステートメントを作成します。注入テストを実行する場合は、渡されるパラメーター itemurl が制御可能であることは明らかです。 SQL インジェクションテストを実行するには、articleurl の値の後に一重引用符を追加するだけです。スクリプトを実行すると、エラーが報告されます。非常によく知られたエラーです。ここで渡します。テスト パラメーターは (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")
です。上記のメソッドを少し変更した後、
t.tips'
を使用します。このメソッドは、文字列のスプライシングを直接使用しません。 %s は、渡されるパラメータを置き換えます。プリコンパイルされた SQL とよく似ていますか?この書き方でSQLインジェクションを防ぐことはできるのでしょうか?テストすると、次の echo
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
は上記のテスト結果と同じであることがわかります。したがって、この方法は不可能であり、この方法はプリコンパイルされた SQL ステートメントではないので、SQL インジェクションを防ぐにはどうすればよいでしょうか?
解決策
2つの解決策
1> PythonのMySQLdbモジュールに付属のメソッドを使用します最初の解決策は、実際には多くのPHPアンチ注射メソッドには、特殊文字のエスケープまたはフィルタリングが含まれます。
2 番目のオプションは、PHP の
PDOに似た内部メソッドを使用することです。ここでは、上記のデータベース クラスを単純に変更できます。
変更されたコード
(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")
executeが実行されると、2つのパラメータが渡されます。1つ目はパラメータ化されたSQL文で、2つ目は、渡されたパラメータを内部で処理します。実際に使用されるメソッドは次のとおりです 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()
これにより、リストを渡した後、MySQLdb モジュールが内部でリストをタプルにシリアル化し、エスケープ操作を実行します。 。
【関連おすすめ】
2.
Geek Academy Pythonのビデオチュートリアル以上がSQLインジェクションを防ぐPythonの方法を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。