Postgresでは、SQLインジェクションから保護するためのメカニズムとして、準備されたクエリとユーザー定義関数は同等ですか?
あるアプローチには他のアプローチに比べて特別な利点がありますか?
Postgresでは、SQLインジェクションから保護するためのメカニズムとして、準備されたクエリとユーザー定義関数は同等ですか?
あるアプローチには他のアプローチに比べて特別な利点がありますか?
回答:
場合によります。
LANGUAGE sql
答えはイエス一般的。
渡されたパラメーターは値として扱われ、SQLインジェクションは不可能です- 本体から安全でない関数を呼び出してパラメーターを渡さない限り。
LANGUAGE plpgsql
答えは通常、はい。
ただし、PL / pgSQLでは、渡されたパラメーター(または部分)がクエリ文字列に連結され、で実行される動的SQLが許可されEXECUTE
ます。これにより、ユーザー入力をSQLコードに変換でき、SQLインジェクションが可能になります。関数本体が適切に処理するかどうかを外部から知ることはできません。ツールが提供されます。
必要な場合にのみ動的SQLを使用してください。パラメーターを値として使用するプレーンSQLステートメントは、SQL関数のようなSQLインジェクションに対して安全です。
以下のために動的SQL、好ましく通過値を持つ値として:
USING
句。例。プリンシパルでのSQLインジェクションを不可能にします。
SQL文字列の値を連結する場合は、次を使用します。
文字列を一重引用符で安全にラップし、構文エラーとSQLインジェクションを回避します。
以下を使用して、SQL文字列内の識別子として扱われるプロセスパラメータ
format()
フォーマット指定子付き%I
。例。quote_ident()
。例。regclass
テーブル名: _tbl::regclass
。例。必要に応じて文字列を二重引用符で安全に囲み、構文エラーとSQLインジェクションを回避します。
関連:
ユーザー入力から文字列を作成して実行するだけではありません。これには、ユーザーによって直接渡された識別子やシステムカタログから取得された識別子が含まれます。動的SQLを構築する場合、すべてをユーザー入力のように扱い、安全に引用する必要があります!
この関連する回答のパフォーマンスへの影響の詳細:
SQLインジェクションの基本:
動的SQLを許可する他のサーバー側言語にも同様の考慮事項が適用されます。
USING
場合はEXECUTE
常に値を渡す句を使用します。あなたは可能性が SQL関数内からPL / pgSQL関数を呼び出し、パラメータを渡します。したがって、絶対に正しいと言えば、安全でない関数を直接または間接的に呼び出さない限り安全です。すべての機能が適切に実行されている場合、それは起こり得ません。