- PR -

OSコマンドインジェクションの防御方法

投稿者投稿内容
もぐ
会議室デビュー日: 2004/01/20
投稿数: 19
投稿日時: 2005-02-15 16:17
引用:

f)に関していえば、Beanのseter、geterで規定桁数に整形してあげればいいと思います。
※ サニタイズはBeanに埋めこみでなくヘルパークラスを用意したほうが良いです。


ヘルパークラスの件は理解ですが、setter/getterでの規定桁数整形というのがイメージがわきません。
Class Sample{
private String data;
public String getData() {
/* Beanから取り出すときにサニタイズ(例:"abcde\;df -k") */
return (String) Helper.sanitize(data); //
}
public String setData(String _data) {
/* Beanにセットするデータはサニタイズ前文字列(例:"abcde;df -k") */
data = _data;
}
 public int lengthData() {
return data.length();
}
}
そして、アプリでデータを利用する場合には、getData()したものを使うので問題なし、一方でlength()チェックの場合には、objSample.getData().length()とはせずに、objSample.lengthData()を利用する?

自分で書きながら何を言っているのかよくわからなくなりましたが、こんな感じでイメージあってますでしょうか?
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2005-02-15 18:31
変な誤解を与えてしまって申し訳ないです。
f )について、ちょっと勘違いしていたので訂正します。

まず、先ほどのリンクからの抜粋です。
引用:
サニタイジングとは入力データから危険な文字を検出し,置換・除去することにより,入力データを無害化する処理である



で、検討するのは。

1.DBに入っていけないデータは何か?
2.Runtime.execなりのコマンド発行で、誤動作する引数の与え方は何か?

の2箇所です。

さらに、XSSなども考えると・・・

(1):URLデコードとDB格納用のサニタイズ
(2):XSS対策用のサニタイズ
(3):コマンド実行用のサニタイズ

コード:
+-----------+      +-----------+      +-----------+     +-----------+
|    (1)    |  --> |   bean    | -+-> |    (2)    | --> | HTML      |
+-----------+      +-----------+  |   +-----------+     +-----------+
                        ∧        |   +-----------+     +-----------+
                        |        +-> |    (3)    | --> | Runtime   |
                        ∨            +-----------+     +-----------+
                   +-----------+
                   |    DB     |
                   +-----------+


と、こんなイメージになります。

beanに直接、サニタイズ後のStringを返すようなメソッドを用意すると後々面倒です。
これも先ほどのリンク先からの引用ですが
引用:

同じデータに誤って2回以上サニタイジングしてデータの意味が変わってしまうという設計上のトラブルも防げる。



桁数整形については勘違いですので、忘れてください。
単純に、DBと同じ形式でデータを保持するほうが良いです<Bean
もぐ
会議室デビュー日: 2004/01/20
投稿数: 19
投稿日時: 2005-02-15 18:58
tak3さん

大変分かりやすい内容、ありがとうございます。
私が勘違いして暴発しておりました。

tak3さんの指摘のおかげで、全体がとても分かった気がします。
最初に私があげておりました、b), f), g) の問題点はクリアになりました。

引用:

(1):URLデコードとDB格納用のサニタイズ
(2):XSS対策用のサニタイズ
(3):コマンド実行用のサニタイズ



気になるのが、私があげていたa)の部分、tak3さんの(3)の存在意義に纏わる部分です。
他の方からもご指摘いただいていますがRuntime.exec()を明示的に行っていない場合には、(3)のサニタイズ処理自体不要と考えてよいものなのでしょうか。

(3)の処理をせずともセキュアなシステムだ、ということが担保出来るのであれば、私があげていたc), d)の懸念はクリアされるのですが・・。


かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-02-16 02:01
Runtime.exec()を行っていないのであれば、
(3)のサニタイズ処理を行う必要がありません。
例えは悪いですが、使っていない変数を宣言するようなものです。

極端な話、画面から入力した値(javaのソース)をサーバでそのままコンパイルして
デプロイして実行してしまうようなアプリなら、
どんなにサニタイズしても無駄でしょうし。
そこまで来ると、セキュリティーマネージャに任せるしかありません。

サニタイズを適切に行えば絶対安全と思われているでしょうが、
適材適所で使用しなければいけません。
べつにサニタイズしなくてもセキュアなシステムは作れますし、
サニタイズしてもセキュリティホールが存在しないと言い切れません。
お使いのJDKやAPサーバにも未知のバグがあるかもしれません。
決してサニタイズ=安全の保障ではありません。

万能な手段はありませんので、対象となるシステムと、
そのシステムに対する入出力の要件をまとめ、
どの入出力のタイミングでどういうサニタイズが必要であるかを検討すべきです。
もぐ
会議室デビュー日: 2004/01/20
投稿数: 19
投稿日時: 2005-02-16 11:15
かつのりさん、こんにちは。

引用:

Runtime.exec()を行っていないのであれば、
(3)のサニタイズ処理を行う必要がありません。



ということは私の懸念は全て解消されます。
確認ですが、私がe)にてあげておりました、以下の件、

引用:

e) サニタイジングの範囲は、あくまでJavaアプリ上のみ、と思っています。つまりはDBにデータ挿入する際は、サニタイジングしていない状態で(元に戻して?)行うべきかと思っています。とすると、万一DBデータに不正データがあった場合には、その値を使うことで不正アクセスされてしまう危険性があると思います。つまり、入力値チェックとは別に、DBデータチェックやファイルデータチェックなど、Javaシステムの外部から入ってくるデータは全てサニタイジングした上で処理しなくてはいけない、という理屈になります。



も結局Runtime.exec()を利用していなければ、問題がない、ということですよね。


やっと一通り理解できました。ご連絡いただいた皆々様、ありがとうございます。

その他、ご指摘等ございましたら是非に。

tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2005-02-16 12:06
引用:

Runtime.exec()を利用していなければ、問題がない


結果としては、その通りです

ただサニタイズは、必要な時点で行なうという点を、理解していますか?

たとえば・・・
1.DBに「あ」という文字が入ってはダメ
2.HTMLで「い」をサニタイズしなければいけない
3.Runtime.exec()を利用する際に「う」をサニタイズしなければいけない

という条件の場合、ユーザ入力で「あいうえ」が入ってきたら

DBには「いうえ」を格納します。(実際には、入力エラーとして再入力させると思いますが)
HTML出力時にはデータ「いうえ」を「うえ」として扱いします
Runtime.exec()ではデータ「いうえ」を「いえ」として扱います。

Runtime.exec()を利用するからといってもDBに「いえ」を格納するわけではありません。
# どうも、この発想になってませんか?

また、他のシステムからの入力の場合DBに「あ」が入ってしまうというのであれば、
条件1の「DBに"あ"という文字が入ってはダメ」を辞めて
条件2、3をそれぞれ
「あい」「あう」をサニタイズするという風に仕様を変更するしかないですよね。

処理の中(処理直前)で、入力データをサニタイズするわけですから、
処理そのもの(Runtime.exec)がなければ、サニタイズ(「う」の無効化)も存在するわけありません。
もぐ
会議室デビュー日: 2004/01/20
投稿数: 19
投稿日時: 2005-02-16 12:15
引用:

ただサニタイズは、必要な時点で行なうという点を、理解していますか?



頭では理解していたつもりでしたが、

引用:

Runtime.exec()を利用するからといってもDBに「いえ」を格納するわけではありません。
# どうも、この発想になってませんか?



この発想になっていました・・。おっしゃるとおり、DBに「う」が入っているのは問題がないわけですので、あくまでRuntime.exec()を行う直前で「う」をサニタイズ、ですね。

理解しました、ありがとうございます!

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