2

ここでPostgreSqlのドキュメントを読んでいて、次のコードスニペットに出くわしました:

EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
   INTO c
   USING checked_user, checked_date;

ドキュメントには、「この方法は、データ値をテキストとしてコマンド文字列に挿入するよりも望ましいことが多い: 値をテキストに変換したり戻したりする実行時のオーバーヘッドが回避され、 SQL インジェクション攻撃を受ける可能性がはるかに低くなります。引用やエスケープの必要はありません。」

このコードが SQL インジェクションの影響を受けやすいことを教えてください。

編集:私が扱った他のすべてのRDBMSでは、これによりSQLインジェクションが完全に防止されます。PostgreSql では何が異なって実装されていますか?

4

3 に答える 3

2

簡単な答えは、それ自体が SQL インジェクションを起こしやすいということではありません。したがって、これが SQL インジェクションにつながる可能性のあるシナリオを探しているmytableので、それがビューである可能性があり、その背後に追加の機能がある可能性があると考えてください。これらの関数は、SQL インジェクションに対して脆弱である可能性があります。

したがって、クエリを見て、SQL インジェクションの影響を受けにくいと結論付けることはできません。あなたができる最善のことは、提供されたレベルで、アプリケーションのこの特定のレベルがここで sql インジェクションの懸念を引き起こさないことを示すことです。

これは、SQL インジェクションが非常によく発生する可能性があるケースの例です。

CREATE OR REPLACE FUNCTION ban_user() returns trigger
language plpgsql security definer as
$$
begin
    insert into banned_users (username) values (new.username);
    execute 'alter user ' || new.username || ' WITH VALID UNTIL ''YESTERDAY''';
    return new;
end;

あなたが示すようにユーティリティ関数をパラメータ化できないことに注意してquote_ident()くださいnew.username

CREATE OR REPLACE VIEW banned_users_today AS
SELECT username FROM banned_users where banned_date = 'today';

CREATE TRIGGER i_banned_users_today INSTEAD OF INSERT ON banned_users_today
FOR EACH ROW EXECUTE PROCEDURE ban_user();

EXECUTE 'insert into banned_users_today (username) values ($1)'
USING 'postgres with password ''boo''; drop function ban_user() cascade; --';

いいえ、使用できるすべての場所で使用しても、問題が完全に解決されるわけではありません。また、適切に使用しても問題が解決するquote_literal()quote_ident()は限りません。

問題は、実行しているクエリよりも常に低いレベルにある可能性があるということです。

于 2013-11-04T10:47:42.830 に答える
1

バインドされたパラメーターは、ゴミがステートメントを操作して、意図した以外のことを行うのを防ぎます。

これにより、Postgres のバグ以外に SQL インジェクション攻撃の可能性がないことが保証されます。(問題が発生する可能性のある例については、 H2C03 のリンクを参照してください。)

「 SQLインジェクション攻撃の可能性がはるかに低い」というのは、そのようなことが発生した場合のCYAの言い回しに相当すると思います。

于 2013-11-01T13:47:18.843 に答える