- - PR -
OSコマンドインジェクションの防御方法
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-02-15 13:52
Javaで作成するWebアプリにおいて、セキュリティを向上させようと思い、@ITの記事を見ていてふと疑問に思いました。
@ITの記事) http://www.atmarkit.co.jp/fsecurity/rensai/webhole02/webhole02.html OSのコマンドインジェクションについてです。 これは記事によると、(1)入力値チェック(2)サニタイジングで防ごう、ということになっています。(1)は当たり前の話なのでよいのですが、(2)の方が具体的によくわかりません。(2)の実装を考えると、いろんな懸念があがってきます。自身でも整理できていないのですが、どなたかアドバイスいただけませんでしょうか。 私の懸念 a) 一般的には、Javaでシステムコマンド発行はRuntime.exec()利用時(ともうひとつあった気がします)であり、それらは通常のJava Webアプリでは利用しないと思っているため、Runtime.exec()している部分だけをチェックすればよいのではないか? b) サニタイジングを行うとしたら、どこで行うのか。XSSのサニタイジングなどは、画面表示時、と相場が決まっているかと思うのですが・・ c) サニタイジングでは、x00(Null)、x20(スペース)などといった制御コードも取り扱うのか。またそのチェックの方法はどうか(HTTPエンコードで、%00、%20みたいな文字で送信されてくると思うのですが、HttpServletRequestから抽出したリクエストデータに、%00という3バイト文字列が発見された場合にサニタイジングするのか?? d) c)と関連して、入力値がダブルバイト文字だった場合など、上記のようなチェックが正しく動かないのではないか? e) サニタイジングの範囲は、あくまでJavaアプリ上のみ、と思っています。つまりはDBにデータ挿入する際は、サニタイジングしていない状態で(元に戻して?)行うべきかと思っています。とすると、万一DBデータに不正データがあった場合には、その値を使うことで不正アクセスされてしまう危険性があると思います。つまり、入力値チェックとは別に、DBデータチェックやファイルデータチェックなど、Javaシステムの外部から入ってくるデータは全てサニタイジングした上で処理しなくてはいけない、という理屈になります。 f) Javaアプリ上でサニタイジングした場合、Javaアプリ上はサニタイジング後のデータを取り扱うことになります。サニタイジング前と後とでデータ長等が変わってしまうような場合には、String.length()等の挙動が異なる場合がありうると思っています・・懸念です。 g) f)と関連して、JavaBeanのフィールド定義などが微妙になる恐れがあります。とはいえ、JavaはCの構造体とは異なり、バイト数を定義する必要等はないので、あまり致命的ではないかもしれませんが・・・少し懸念です。 h) 素朴な疑問ですが、そもそも皆さん、どうやってコマンドインジェクションを回避しているのでしょう??? [ メッセージ編集済み 編集者: もぐ 編集日時 2005-02-15 13:52 ] | ||||||||
|
投稿日時: 2005-02-15 14:29
コマンド実行を許可しない、とか。 | ||||||||
|
投稿日時: 2005-02-15 14:40
それというのは、WebApp実行ユーザのシェル権限を与えないことによって、OSコマンドを無効化する、ということでしょうか? 前に見たサイト(Apacheのセキュリティなサイトだったと思います)で、 useradd ...... -s /dev/null username でusernameのシェルが無効化可能、みたいに書いてあったのですが・・。 今回、まだシステムを構築する環境が決定しておらず、もの(HW/SW)が手元にないため検証できていませんが、試してみようとは思っています。 ただ、@ITの記事などでは、yuzyさんご指摘の方法などは紹介されていなかったので、そのような防御手段は100%ではないのかもしれないな??と心配になってしまいます。 (私の理解だと、それで100%OKな気もするのですが・・) | ||||||||
|
投稿日時: 2005-02-15 15:17
私が思ったのは、そんな大それたことではなくて、 コマンド実行しなければいいんじゃないの? ということです。 ユーザが入力した文字を使ってコマンド実行させる、 なんて要求が私には考えられません。 | ||||||||
|
投稿日時: 2005-02-15 15:25
セキュアプログラミングなら、こちらの情報がおすすめです。
http://www.ipa.go.jp/security/awareness/vendor/programming/index.html サニタイジングの対象とタイミングについては、必要なものだけ実施で問題無いと思います。 「クロスサイトスクリプティング対策の詳細」でサニタイズの概念を説明しています。 f)に関していえば、Beanのseter、geterで規定桁数に整形してあげればいいと思います。 ※ サニタイズはBeanに埋めこみでなくヘルパークラスを用意したほうが良いです。
まったく同感です [ メッセージ編集済み 編集者: tak3 編集日時 2005-02-15 15:26 ] | ||||||||
|
投稿日時: 2005-02-15 15:28
私もそのような要求など考えられない口です(WebからFTPコマンド実行してしまうイントラ向けシステムを少し前に見ましたが・・)。なので、以下のように書いていても、明示的にシステムコード発行などはありえないと思っています。
しかし・・・それ以外の部分でも、セキュリティレベル向上を図りたいと思っています。 | ||||||||
|
投稿日時: 2005-02-15 15:50
こんにちは。
例えば指定された文字列を使用した検索系などでは使わざるを得ないと思いますが。 コマンドを実行させることそのものが目的の場合は返って比較的安全で(しっかりチェックしますので)、文字データをただ扱っているだけと思っているときが一番危ないです。 この問題ってそういうことだと思うのですが。 | ||||||||
|
投稿日時: 2005-02-15 15:59
検索処理は通常、DBに対して行うのが一般的ではないでしょうか。 今、私が(勝手ながら)話題としたいのは、OSコマンドのインジェクション話でして、SQLインジェクション等については、JavaだとPreparedStatementを利用して問題なしに出来るかと思っています。 また、例えばユーザ入力値(Xとします)を含むファイルを検索するとした場合も、出来ればRuntime.execは利用せず(Runtime.exec("find -name X ...")みたいなのではなく)、Javaで提供されているラッパ(Jakarta Commonsあたりが出してそうな気がします。ちゃんと調べてませんが)を利用することでセキュアな開発が可能なのかな?と思っています。(例えば・・そんなのないにしても、Find.setName(X); Find.do();みたいなイメージかと) もちろん、各種JavaAPIも突き詰めていけばOS Nativeコードを呼び出しているので、そこにバグがあった場合にはどれだけRuntime.execを利用せずともOSバグを突くことは避けられないとは思いますが。 okutinさんがいっておられるイメージと違っていたらすいません。ご指摘ください。 |