web-dev-qa-db-ja.com

Postgres関数でのSQLインジェクションと準備済みクエリ

Postgresでは、準備されたクエリとユーザー定義関数はSQLインジェクションから保護するメカニズムと同等ですか?
1つのアプローチに他のアプローチよりも特定の利点はありますか?

場合によります。

SQL関数

_LANGUAGE sql_ を使用すると、答えは通常はyes になります。

渡されたパラメータはvaluesとして扱われ、SQLインジェクションは不可能です-安全でない関数を本体から呼び出さない限りパラメータを渡します。

PL/pgSQL関数

_LANGUAGE plpgsql_ の場合、答えはnormallyyes です。

ただし、、PL/pgSQLでは動的SQL を使用できます。ここで、渡されたパラメーター(または部分)がクエリ文字列に連結され、EXECUTE。これはユーザー入力をSQLコードに変換し、SQLインジェクションを可能にします。関数本体が適切に処理するかどうかは、外部からはわかりません。ツールが提供されます。

動的SQLは、必要な場所でのみ使用してください。パラメータを値として使用するプレーンSQLステートメントは、SQL関数のようなSQLインジェクションに対して安全です。

動的SQL の場合、valuesを次の値として渡すことができます:

  • USING句。

プリンシパルでSQLインジェクションを不可能にします。

SQL文字列でvaluesを連結する場合は、次を使用します。

文字列を single-quotes で安全にラップし、構文エラーとSQLインジェクションを回避します。

SQL文字列でidentifiersとして扱われるプロセスパラメータ:

文字列を double-quotes 安全に必要な場所で囲み、構文エラーとSQLインジェクションを回避します。

関連:

Never ユーザー入力から文字列を構築して実行するだけです。これには、ユーザーによって直接渡された、またはシステムカタログからフェッチされた識別子が含まれます。 Allは、ユーザー入力のように処理し、動的SQLを構築するときに安全に引用する必要があります。

この関連回答のパフォーマンスへの影響の詳細:

SQLインジェクションの基本:

動的SQLを許可する他のサーバー側言語にも同様の考慮事項が適用されます。

37