SQLインジェクションに対して安全ですか
-
06-07-2019 - |
質問
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を生成していないので、これは(私には)安全に見えます。
ストアドプロシージャを呼び出しているデータがどこから来ているのかわかりません。そのため、バッファオーバーフローなどから保護する必要があります。
参照ホワイトリスト。他の特定の条件に従えば、これは問題ありません。すべての入力を最も単純な形式に分解することは絶対に必須です。したがって、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インジェクション攻撃