psqlでSQLを実行する場合、あまり外部から来た値は使わないので、SQL埋め込み時にエスケープしないと思います。
例えば、以下のようにシェル変数をINSERT
に埋め込んで実行する場合、一見、問題なさそうに見えますが、
$ v=foo
$ psql -c "INSERT INTO t VALUES ('$v')"
INSERT 0 1
$ psql -c "SELECT * FROM t"
c
-----
foo
(1 行)
シェル変数に悪意のあるSQLを含めると、以下のようにINSERT
の後に別のSQLを実行でき、SQLインジェクションができてしまいます。
$ v="foo'); TRUNCATE t; --"
$ psql -c "INSERT INTO t VALUES ('$v')"
INSERT 0 1
TRUNCATE TABLE
$ psql -c "SELECT * FROM t"
c
---
(0 行)
そのような場合、psqlには-v
または--set
、--variable
オプションで変数を渡して、SQL内で:'変数名'
という形で参照する機能があって、この機能を使うと、以下のように値が自動的にエスケープされて、SQLインジェクションを防ぐことができます。
$ v="foo'); TRUNCATE t; --"
$ echo "INSERT INTO t VALUES (:'v')" | psql -v v="$v"
INSERT 0 1
$ psql -c "SELECT * FROM t"
c
-----------------------
foo'); TRUNCATE t; --
(1 行)
この機能を使う際の注意点としては、-c
または--command
オプションで指定したSQLでは変数を参照できないので、SQLをファイルに記述して-f
または--file
オプションでファイル名を指定するか、上記のように標準入力から読み込む必要があります。