連載
» 2008年03月05日 00時00分 公開

Tomcatはどこまで“安全”にできるのか?(5):無料でWebアプリにありがちな脆弱性を調べて治す (3/3)

[x-labチーム,株式会社アメニクス]
前のページへ 1|2|3       

クロスサイトスクリプティングを解消するには?

 XSSの対策といっても、何をすればいいのでしょう?

文字コードのエスケープ

 一番スタンダードな方法は、フォームから送られてくる文字列をHTMLタグとして解釈されないように、一部の記号をWebブラウザ上での表示に利用できる実体参照に変換する方法です。

 一般的によく狙われる文字は以下の表にまとめてあります。内容に変換するようにコードを変更すれば、対策可能です。

変換する文字 変換後の文字
< &lt;
> &gt;
&#39;
&quot;
 (スペース) &nbsp;

 POSTでのフォーム送信には失敗し、GETでのリクエスト処理には無反応という結果が分かっています。なぜ、このようなことになっているのでしょうか?

 それは、このWebアプリケーションではPOSTによって受け渡されたデータをチャット内容として送信していたからです。

該当部分のソース
if ("POST".equals(request.getMethod())) {
    final String user = request.getParameter("user");
    final String message = request.getParameter("message");
    messageSender.send(user,message);

    event.close();
    return;
}

 ここの処理で上記表の対応文字の変換を行ってあげればいいのです。

 例えば、以下のようなファンクションを作成してこのファンクションで文字列を処理してあげればよいのです。

public String encodeHTML(String str){
    String s = str;
    s = s.replace(">","&gt;");
    s = s.replace("<","&lt;");
    s = s.replace("\"","&quot;");
    s = s.replace("\'","&#039;");
    s = s.replace(" ","&ensp;");
    return s;
}

チャットアプリの脆弱性を直す

 それでは、実際に第3回に作成したサーブレットに組み込んでみましょう。まずは、サーブレットの設置されたディレクトリに移動します。移動したら、サーブレットの作成に移ります。Cometはイベント受信後、エディタでCometServlet.javaを作成します。サーブレットには、以下の内容を記述していきます。

CometServlet.java(※赤の部分が追加した部分)
……(省略) ……
    
public class CometServlet
extends HttpServlet implements CometProcessor {


……(省略) ……
    
    public void event(CometEvent event)
    thro ws IOException, ServletException {

        HttpServletRequest request = event.getHttpServletRequest();
        HttpServletResponse response = event.getHttpServletResponse();

        if ("POST".equals(request.getMethod())) {
            final String user = encodeHTML(request.getParameter("user"));
            final String message = encodeHTML(request.getParameter("message"));
            messageSender.send(user,message);

……(省略) ……
    
    public String encodeHTML(String str){
        String s = str;
        s = s.replace(">","&gt;");
        s = s.replace("<","&lt;");
        s = s.replace("\"","&quot;");
        s = s.replace("\'","&#039;");
        s = s.replace(" ","&ensp;");
        return s;
    }

}

 以上でサーブレットの修正は完了しました。それでは、修正したサーブレットをコンパイルしましょう。

javac -classpath /opt/tomcat6/lib/servlet-api.jar:/opt/tomcat6/lib/catalina.jar CometServlet.java

 最後に、Tomcatの再起動を実行します。

/etc/rc.d/init.d/tomcat restart

 それでは、あらためてXSSが発生しないかどうか、確認してみましょう。各入力項目に「<script language="javascript">alert('hoge')</script>」を入力します。

図9 図9

 そして、送信ボタンを押すと……。

図10 図10

 無事に入力した内容がそのまま画面に表示されるようになりました。このページのソースをテキストエディタでのぞいてみます。

[<language="javascript"?script>alert('hoge')</script>]: <language="javascript"?script>alert('hoge')</script>

 この内容が以下のように変換されていました。

[&lt;script&ensp;language=&quot;javascript&quot;&gt;alert(&#039;hoge&#039;)&lt;/script&gt;]: &lt;script&ensp;language=&quot;javascript&quot;&gt;alert(&#039;hoge&#039;)&lt;/script&gt;

 「<」や「>」などのタグの開始と終わり、「'」や「"」などの文字列を表す記号、半角スペースも正しく実体参照に変換されていました。

 今回のチャットアプリケーションでの対応はここまでにしますが、利用する言語やケースに応じて以下の文字についても対応することを検討した方がよいでしょう。

変換する文字 変換後の文字
( &#40;
) &#41;
# &#35;
& &amp;

コラム 「注意! 文字のエスケープも完全な方法とはいえません」

  • HTMLエンコードによる文字判別の差異を利用して違う文字コードの文字列を利用してスクリプトを混入させる方法
  • CSSが任意に入力できる状況でJavaScriptを混入させて実行させる方法


上記のような方法も実際には確認されていますので、下記のことは必ず忘れずに気を付けておきましょう。


  • 画面描画に関する文字列の制御は正しく行う
  • 文字コードの指定は忘れずに行う

脆弱性を見逃さないためには

 Webアプリケーションの脆弱性は開発者ならいつも気にしなければいけないことですが、見落としたり気付かなかったりすることが多いので、自動的にチェックしてくれるツールを活用したり、よくあるセキュリティホールだけでも定期的に確認することでセキュリティ被害に遭わないように努めていきましょう。

 次回で連載はいよいよ最後になりますが、アプリケーションを提供するユーザーによる悪意のある攻撃やミスによるトラブルを未然に防ぐための機能「セキュリティマネージャー」について解説します。

著者プロフィール

x-lab チーム

株式会社アメニクスのR&D部門として、企業の価値向上を目的に結成された研究開発チーム(x-lab=amenix laboratory)。

アメニクスの社員をはじめ、システム開発技術者のみに限らず、MBA教授や外資系出身エンジニアなど幅広いメンバーが所属している。IT技術からマーケティング、金融テクノロジーなどさまざまな分野で活動中。


主な著書

『最速導入!オープンソースでつくる実用オンラインショップ』



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。