- PR -

パラメタライズドクエリでのテーブル指定

投稿者投稿内容
未記入
ベテラン
会議室デビュー日: 2003/06/26
投稿数: 76
投稿日時: 2006-08-03 23:57


[ メッセージ編集済み 編集者: 未記入 編集日時 2007-01-19 21:49 ]
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2006-08-04 00:35
引用:

あと、SQLインジェクションのことをもっと詳しく調べた方が良いですよ。簡単に回避できるし、余計な心配して複雑怪奇なコーディングするよりも。



テーブル名のSQLインジェクションに限定するなら、半角スペースと、セミコロンぐらいのチェックだけで良さそうな気もしますね。
これらはテーブル名に使用できないはずだから、無条件ではじいて問題なさそうですし。
がんふぃーるど
ベテラン
会議室デビュー日: 2006/06/05
投稿数: 58
お住まい・勤務地: さいたま
投稿日時: 2006-08-04 00:37
ストアドを使用する場合でも、ストアド内部でSQL文を(入力値値を用いて)動的に作成する
のであれば、sp_executesqlを使用してパラメタライズドクエリを実行すべきだと思います。

ぜうすさんの方法だとVB側でガリガリSQL文を作成するのと同じ結果になってしまいますね。
SELECT文がコンパイルされる前に入力値とSELECT文を結合してしまえば、それだけで
SQLインジェクションの危険性があります。(入力値を事前に検証していれば別ですが…)

テーブル名、列名がユーザから入力されないのですから、VB側でテーブル名と列名を
文字列結合して、キーの部分をパラメータ化したパラメタライズドクエリを使用するのが
私としては良いと思います。
vincent
大ベテラン
会議室デビュー日: 2004/07/09
投稿数: 142
投稿日時: 2006-08-04 10:06
データベース側にビューを用意しておくってのはどうでしょうか。
32WH
会議室デビュー日: 2006/08/03
投稿数: 15
投稿日時: 2006-08-04 12:17
皆様、こんな初心者質問に多数の回答有難うございます。

ぜうす様
回答有難うございます。

実際にストアドを組んでやってみました。
やってみた結果としてはDelete文を組み込むことも可能だったので、
ちょっと今回の実装には出来そうに無いです…。
やっぱりお客さんに現状報告してどうにかできないか確認してみます。
SQLインジェクションについてはまだまだ知識が足りないみたいです…
色々資料をあさってこれを機に深く勉強してみようかと思います。
有難うございます。


burton999様
度重なるご回答有難うございます。
引用:

テーブル名のSQLインジェクションに限定するなら、半角スペースと、セミコロンぐらいのチェックだけで良さそうな気もしますね。
これらはテーブル名に使用できないはずだから、無条件ではじいて問題なさそうですし。



とのことですが、実際にテーブルを作ってみました。
Table_A];delete from [Table_B
て感じのテーブルが作れてしまいました…
単純にセミコロン、シングルクォート、ダブルクォートを
無効化(Replace等)してしまうようにすれば良いですかね?

がんふぃーるど様
ご回答有難うございます。

sp_executesqlですか、これも初めて聞きました。
調べてみましたが、ストアド内でのパラメタ化クエリが使用できるみたいですね!
実装してみたのですが、やはりこれもテーブル名等は
パラメタ化できないみたいで…
やり方の問題ですかね?

vincent様
ご回答有難うございます。

引用:

データベース側にビューを用意しておくってのはどうでしょうか。



とのことですが、どのようなビューを実装したらよいのでしょうか?
今回の問題に対して、ビューと言うアプローチ方法が浮かびません…
何か良い方法があれば教えていただいてもよろしいでしょうか?
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2006-08-04 12:41
引用:

引用:

データベース側にビューを用意しておくってのはどうでしょうか。


とのことですが、どのようなビューを実装したらよいのでしょうか?
今回の問題に対して、ビューと言うアプローチ方法が浮かびません…
何か良い方法があれば教えていただいてもよろしいでしょうか?



引用:

今回こんなつくりになった理由はデータパターンにより、
取得するテーブルもキーも全て違う、
(但し取得項目は同じ)


という条件を生かし、各テーブルをunionで連結し、
どのテーブルから読み出すかを識別子(連番でも、テーブル名でもお好きなように)を付与しておく。

コード:
ex)
create view hoge_view (
id, c1, c2, ...
) as
select 1, t1.c1, t1.c2, ...
from table_A t1

union all

select 2, t2.f1, t2.f2, ...
from table_B t2

union all ....


ってな感じ?

unionで連結するので、列数、列の型は合わせとくように。

囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-08-04 12:42
テーブル名や列名をパラメタにする方法を少なくとも私は知りません。
何でもかんでも SQL インジェクションの心配をしていたらキリがないですよ?

例えば以下は文字列連結をしていますが、
コード:
private const string tableName = "TableA";
・・・

public DataSet GetDataSet()
{
	string query = "SELECT * FROM " + tableName;
	・・・
}


「クエリを文字列連結しているようだけど、サニタイズしなくていいの?」と言う人がいるでしょうか。

32WHさんの場合は、どこからテーブル名や列名が来るのか、そこがハッキリしたら
引用:

ユーザがセキュリティにうるさい為、ここに対しての
突っ込みを無くしたいが為に今回の投稿をしました


突っ込みを無くせるでしょう。
_________________
囚人のジレンマな日々
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2006-08-04 16:57
複雑怪奇なことをしても逆に穴を作るだけだったりします

string query = "SELECT * FROM [" + tableName.Replace("]","]]") + "]";

これじゃだめですか?(参考) ほかにエスケープしなきゃならん文字あるのかな。。
インジェクション対策を破れるかテストしてみてください。(だめだったらごめんなさいね。。w)

この手の対策の類は「ダメな文字」をエスケープするか、エスケープする方法がないなら消す、でほとんど済みます。

#私の最初の投稿ではインジェクション対策してません。

スキルアップ/キャリアアップ(JOB@IT)