2017-10-27 2 views
0
CREATE OR REPLACE FUNCTION increment(key character varying) 
RETURNS character varying AS $$ 
BEGIN 
     SELECT code, name from tbl where $1; 
END; 
$$ LANGUAGE plpgsql; 


select * from increment('code = ''ati'' '); 

=>通知エラー "where $ 1";postgresqlエラーで関数を作成します。

+1

'$ 1'は' $ 1'を意味しています - そしてvarcharを定義しています... '' SELECT code、tbl where name = $ 1; ''を意味するかもしれませんか?.. –

+0

where句'where column = $ 1'のようなものでなければなりません。 – JustMe

+0

私は知っています。 functionのパラメータは 'name = ...'です – NiemNV

答えて

1

何をやろうがSQLインジェクションにプルーン、例えば次のとおりです。

t=# CREATE OR REPLACE FUNCTION increment(key character varying) 
RETURNS character varying AS $$ 
BEGIN 
return format('SELECT code, name from tbl where %s',$1); 
END; 
$$ LANGUAGE plpgsql; 
CREATE FUNCTION 
Time: 1.179 ms 
t=# select * from increment('code = ''ati'' '); 
        increment 
------------------------------------------------ 
SELECT code, name from tbl where code = 'ati' 
(1 row) 

いますが、文が返されるかを制御していない、ここを見て:

t=# select * from increment('true; drop table b;'); 
         increment 
------------------------------------------------------ 
SELECT code, name from tbl where true; drop table b; 
(1 row) 
+0

おそらくdsqlでキーを実行して真を返すかどうかを確認します: 'execute 'select' || some_booleanにキーを押します。エラーが発生した場合は、残りの部分を実行しないでください。 – JustMe

+1

'' 'do $$ begin 'を実行します。ドロップテーブルb; '; end; $$ ; '' '安全に落としたテーブル –

+1

@JustMeそれは役に立たないでしょう。攻撃者は代わりに最初の 'EXECUTE'のコンテキストで動作するように攻撃を調整することができます。さまざまなコンテキストに対してSQLインジェクション攻撃を構築するさまざまな方法に関する膨大な研究があります。 – IMSoP

1

を機能は、単にしません変数を連結して結果のSQLを実行するので、WHERE句全体をそのようなパラメータとして渡すことはできません。

最大の理由はセキュリティです。関数への入力は最終的には信頼できないユーザー(Webサイトからの入力など)からのもので、クエリを任意に変更できないようにする必要があります。姓O'Reillyを検索する場合は、'がエスケープされているかどうかを追跡していないと機能が壊れることになります。

代わりに、クエリとデータは別々に保持されます。WHERE $1が動作する唯一の時間は、$1がブール値の場合です。同様に、WHERE name=$1は今までなど、適切な値(おそらくtextまたはvarchar)、反対nameを比較します

あなたが本当に非常に頻繁に使用する場合は、時折起こる動的SQLクエリのために必要があるが、いない場合は、言ったことすべてあなたのDBをうまく設計したら、a plpgsql function with an EXECUTE statementを使うことができます。この場合

、あなたはおそらく、入力がcodeの値になりたい、とクエリが明示的にチェックするために:

SELECT code, name from tbl where code = $1; 

あなたはその後、別のユースケースのためのバリアント機能を追加、または明示的なことができますsearch_by_nameのようなブール型フラグは、動的SQLのリスクと複雑さのない、異なるクエリを選択します。

関連する問題