web-dev-qa-db-ja.com

psycopg2およびSQLインジェクションセキュリティ

より大きなモデリングアルゴリズムの一部として使用されるクラスを書いています。私の部品は空間分析を行って、特定のポイントから他のポイントまでの距離を計算します。返される距離の数、カットオフ距離など、さまざまな条件があります。

現在、プロジェクト仕様はハードコードされた状況のみを示しています。つまり、「関数#1は、500m以内にポイントセットAからポイントセットBまでのすべての距離をリストする必要があります。関数#2は、ポイントセットCからポイントセットD ...までのすべての距離をリストする必要があります。」などのようになります。

これらのパラメーターをハードコーディングしたくないし、モデルの次の段階を開発している人も、パラメーターを微調整したり、異なる条件を持つ他のプロジェクトでアルゴリズムを再利用したりすることを望んでいないため、 。

今問題は、これを行うためにpsycopg2を使用していることです。これは私が働く標準なので、それから逸脱するという選択肢はありません。 SQLインジェクションの明らかな理由により、実行されたクエリにパラメータとして入れられるパラメータを公開することは非常に悪い考えだと私は読んだ。しかし、psycopg2はSQL入力を自動的にサニタイズすると考えました。問題はAsIs関数を使用していることだと思います。

簡単な解決策は、プロジェクトで指定されたとおりにハードコードすることですが、これは私には怠惰でずさんな感じがします。私は怠惰でずさんな仕事をするのが好きではありません。

ユーザーがpsycopg2で実行されるクエリに入力されるパラメーターを入力できるようにしても、安全ですか?または、AsIsを使用しているだけで安全ではありませんか?ユーザーがこれらのパラメーターを入力できるようにしたい場合、自分で入力をサニタイズする責任を負う必要がありますか。そうであれば、別のpythonライブラリか何か?

9
wfgeo

psycopg2.sql を使用して動的クエリを作成できます。 AsIsとは異なり、SQLインジェクションから保護されます。

1
piro

AsIsは、自分が何をしているか本当に理解していない限り、安全ではありません。単体テストなどに使用できます。

SQLクエリを事前にフォーマットしない限り、パラメーターを渡すことはそれほど安全ではありません。決してしません:

_sql_query = 'SELECT * FROM {}'.format(user_input)
cur.execute(sql_query)
_

_user_input_は、たとえば_';DROP DATABASE;'_になる可能性があるため。

代わりに、次のようにします。

_sql_query = 'SELECT * FROM %s'
cur.execute(sql_query, (user_input,))
_

_pyscopg2_はクエリをサニタイズします。また、ユーザーの入力を本当に信頼しない場合は、独自のロジックを使用してコード内のパラメーターを事前にサニタイズできます。

_psycopg2_のドキュメント ごと:

警告決して、決して、決してPython文字列連結(+)または文字列パラメーター補間(%)を使用して、SQLクエリ文字列に変数を渡さないでください。

また、クエリを実行する必要があるテーブルをユーザーに通知することは決してありません。アプリのロジック(またはルート)でそれがわかるはずです。

AsIs()について、 _psycopg2_のドキュメント に従って:

Asis()...文字列表現がSQL表現としてすでに有効なオブジェクト用。

したがって、ユーザーの入力には使用しないでください。

10

クエリを変数に格納する必要がある場合は、SQLメソッド( documentation )を使用できます。

from psycopg2 import sql


query = sql.SQL("SELECT * FROM Client where id={clientId}").format(clientId=sql.Literal(clientId)
0
Dan.faudemer