動的SQLを使用する関数でパラメーターを使用する場合、PostgreSQLでワイルドカード検索を実装する適切な方法は何ですか?
開始点として、以下は、スタックオーバーフローに関する別の質問に答えるErwin Brandstetterの例です。
https://stackoverflow.com/a/12047277/538962
CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
, ends_with text = NULL)
RETURNS SETOF lookups.countries AS
$func$
DECLARE
sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
IF ends_with IS NOT NULL THEN
sql := sql || ' AND country_name <= $2';
END IF;
RETURN QUERY EXECUTE sql
USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
country_name
先頭と末尾のワイルドカード検索を実行したいと考えていました。
たとえば、パラメータを使用せずに、AND country_name LIKE '%ic%'
。
SQLインジェクションのリスクを否定することに関して、このシナリオでワイルドカード検索を実装する最良の方法は何ですか?
country_name
で、先頭と末尾のワイルドカード検索を実行したいとします。
これには動的SQLは必要ありません。ただ:
CREATE OR REPLACE FUNCTION report_get_countries_new (_pattern text)
RETURNS SETOF lookups.countries AS
$func$
SELECT *
FROM lookups.countries
WHERE country_name LIKE '%' || _pattern || '%'
$func$ LANGUAGE sql;
コール:
SELECT * FROM report_get_countries_new ('ic'); -- without wildcards!
これは、SQLインジェクションのリスクを完全に無効にします。
呼び出し元はワイルドカードを自由に含めることができます(パラメーターを処理してワイルドカードをフィルター処理しない限り)。ただし、ハードコーディングされた先頭のワイルドカードと後続のワイルドカードがあります(パラメーターが\
で終了し、末尾の%
から特別な意味が削除されている場合を除く)。
PL/pgSQLで動的SQLとEXECUTE
を使用する場合でも、USING
句を使用して値をvaluesとして渡す限り、SQLインジェクションのリスクはありません。
関連: