質問

PostgresSQLでそのようなものを使用するとき、SQLインジェクションに対して安全かどうかを知りたい:

CREATE or REPLACE FUNCTION sp_list_name( VARCHAR )
RETURNS SETOF v_player AS '
   DECLARE
      v_start_name ALIAS FOR $1;
      r_player  v_player%ROWTYPE;
      v_temp VARCHAR;
   BEGIN
      v_temp := v_start_name || ''%'';
      FOR r_player IN
         SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
      LOOP
         RETURN NEXT r_player;
      END LOOP;
      RETURN;
   END;
' LANGUAGE 'plpgsql' VOLATILE;

この関数を使用して、文字で始まるプレイヤーの名前を一覧表示します。

select * from sp_list_name( 'A' );

Aで始まる姓を持つプレイヤーを提供します。

SQLを挿入しようとしました

select * from sp_list_name( 'A; delete from t_player;--' );
select * from sp_list_name( '''; delete from t_player;--' );

安全ですか?

どのような場合に注射できますか?

よろしく

役に立ちましたか?

解決

プロシージャの点では、SPの変数はコードに展開されないため安全と思われますが、" SELECTのようなパラメータ化されたクエリを使用しない場合でも、自分自身を公開できます。 * FROM sp_list_name(?); " アプリケーションコードで。 " SELECT * FROM sp_list_name( '$ start_name'); "のようなもの" ')の開始名を渡すユーザーによって破壊される可能性があります; last_name NOT IN(' "からt_playerから削除します。プログラムへの入力。

NB:ストアドプロシージャ内の変数は、 'または;、を含んでいても コードに展開されないことに注意してください(への受け渡しを除く) replace 関数ではなく、 quote_literal を使用する EXECUTE )そのように交換;または 'は完全に不要です(ストアドプロシージャでは、もちろんそれを使用するアプリケーションは別の話です)。常に" tl; dr "または" O'Grady "チーム。

Leo Moore、Karl、LFSR Consulting :ストアドプロシージャの v_temp_name はSPのコードに展開されません( > EXECUTE )、SPではなくアプリケーションでチェックを実行する必要があります(またはOPは、代わりにアプリコードでパラメーター化されたクエリを使用できます)。他の人が提案していることは、心配することに似ています

my $bar = "foo; unlink('/etc/password');"; 
my $baz = $bar;

評価がない場合に実際にリンク解除を実行します。

他のヒント

SQLインジェクションを防ぐためのルール#1:信頼できない/制御できない誰か/何かからの入力をすべてサニタイズします。

問題自体はデータベースコード内にあるのではなく、これらのステートメントを実行しているアプリケーションにあります。

SQLインジェクションから保護する適切な方法は、ホワイトリスト *です。 shortは、受け入れる文字を設定し、除外します。

間違った方法は、ブラックリスト-受け入れられない文字をリストするブラック攻撃者に追いつくことができないため、トラブルにつながります。 ASCIIテーブル、エスケープ文字などを使用してブラックリストを回避する方法があります。

また、あなたのサイトで試してみるのに良いチートシートもあります。いくつかのテストを実行し、失敗するように試みます。

* アプリケーションではなく、DB(Thanks James)

あなたは自分でSQLを生成していないので、これは(私には)安全に見えます。

ストアドプロシージャを呼び出しているデータがどこから来ているのかわかりません。そのため、バッファオーバーフローなどから保護する必要があります。

参照ホワイトリスト。他の特定の条件に従えば、これは問題ありません。すべての入力を最も単純な形式に分解することは絶対に必須です。したがって、SQLクエリ名、単一引用符などをチェックするだけではありません。他の文字セットを使用して表現またはエンコードできます。 SQLキーワード自体。

私は、保護されたリソースへのユーザー名/パスワードを許可する特定のクライアントで働いていました(最終的には空港の安全な部分へのアクセスパスを取得できます!)。ログオンフィールドを回避するには、「」と入力し、そこからSQLクエリを作成してユーザーアカウントとパスワードを取得します。

問題は、クライアントがすでにWeb開発を行ったことがないように見えるベンダーでサイトを構築し、すでに20万を吹き飛ばしていたことでした。修正はさらに£ 60kであり、union、select、その他のキーワードをチェックするだけの検証func()でした。彼らがcanicolisation / encodingのために何をしたか(それについて説明しなければならなかった)について尋ねられたとき、それはタンブルウィードの時間でした。

開発ハウスと(高価な)プロジェクトは缶詰になりました。

 v_start_name 
のコンテンツの検証を検討できます。セミコロン、コメント文字、等号などの文字列を確認します。Chars値とHex値の両方を必ず確認してください。ハイフンで区切られた名前を許可することを忘れないでください。 「Smith-Brown」は許容される可能性が高い「Smith--Brown」は潜在的に注入です。

SQLインジェクションの16進数に慣れていない場合は、次の簡単な紹介

http:// www .arejae.com / blog / sql-injection-attack-using-t-sql-and-hexadecimal.html

http://www.securityfocus.com/infocus/1768

DECLARE
      v_start_name ALIAS FOR $1;
      r_player  v_player%ROWTYPE;
      v_temp VARCHAR;
   BEGIN
      --  new pseudo code here
      if v_start_name has bad chars exit with error message
      -- end pseudo code here
      v_temp := v_start_name || ''%'';
      FOR r_player IN
         SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
      LOOP
         RETURN NEXT r_player;
      END LOOP;
      RETURN;
   END;

よろしく カール

v_start_nameを置き換えるだけで&quot ;;"を削除できます。など。

v_clean_name VARCHAR;
Select v_clean_name = Replace(v_start_name,';','');

これにより、; SQLインジェクション攻撃を阻止する空白を使用

詳細については、 PostgresSQLの文字列関数

As LFSR Consultingもコメントしました。 BlackListよりもWhiteList(つまり、「;」などの無効な文字を含む入力を処理しない)の方が良い(つまり、ユーザーがReplaceに対してSQLインジェクション攻撃を行う可能性があるため、データをクリーンアップしてみてください)。

詳細については、 SQLインジェクション攻撃

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top