私はこのようなエクトクエリを構築しています:生のSQLをログに記録することはできますか?
from item in query,
where: like(item.description, ^"%#{text}%")
私は、これはtext
でSQLインジェクションを可能にすることを心配。これを修正する前に、クエリが実際にデータベースにどのように送信されているかを確認したいと思います。
もし私がinspect the queryを見るか、または記録されているものを見ると、私はいくつかのSQLを見ますが、それは無効です。例えば
、クエリを検査することは私にこの示しています。私はコピーしてpsql
にそれを貼り付ける場合、
SELECT i0."id", i0."store_id", i0."title", i0."description"
FROM "items" AS i0 WHERE (i0."description" LIKE $1) ["%foo%"]
しかし:私はRepo.all
にこのクエリを渡すと、それはこれをログに記録
{"SELECT i0.\"id\", i0.\"store_id\", i0.\"title\", i0.\"description\"
FROM \"items\" AS i0 WHERE (i0.\"description\" LIKE $1)",
["%foo%"]}
をPostgreSQLは私にエラーを返します:
ERROR: 42P02: there is no parameter $1
oughエクトは、実際にこのように、parameterized queryをやっていることがあります。
PREPARE bydesc(text) AS SELECT i0."id",
i0."store_id", i0."title", i0."description"
FROM "items" AS i0 WHERE (i0."description" LIKE $1);
EXECUTE bydesc('foo');
もしそうなら、私は、SQLインジェクションを防ぐだろうと思います。しかし、私はちょうどこれがEctoのことだと推測しています。
Ectoが実行している実際のSQLをどのように確認できますか?
「クエリ構文には、SQLインジェクションが可能でないコンパイル時に検証します。」 Ectoが 'like(item.description、^"%#{text}% ")'をコンパイルするとき、 'text'のエスケープを追加すると言っていますか? PostgreSQLはプリペアドステートメントを使用しているだけなので、安全です。そうすれば、PostgreSQLは(例えば)単一の 'SELECT'と*' * SELECT'の後に 'DROP TABLE'を実行することを前もって知っていますか? –
エスケープしません。パラメータを使用します。 '%foo%'は決してクエリの一部ではないので、クエリに何も挿入することはできません。それは、準備されたステートメントへのパラメータとして完全に別々に渡されます。 – michalmuskala
また、プリペアドステートメントには1つのステートメントしか含めることができないので、 ' - ;のようなものを追加することはできません。 DROP TABLE' - postgresは2つの式を1つに入れようとしていると言っています。 – michalmuskala