Webセキュリティの小部屋

Twitter のフォローはこちらから Facebook ページはこちら RSSフィードのご登録はこちらから
公開日:2013年3月16日
最終更新日:2020年8月20日

クロスサイト・スクリプティング(XSS)対策(Java編)

クロスサイト・スクリプティング(以下、XSS)の対策は以下の記事を参照してください。

これを Java で実現すると以下のようになります。

根本的対策

■1.HTTP レスポンスヘッダーに文字コードを指定する
Java でレスポンスヘッダーの Content-Type に文字コードを指定するには、サーブレットと JSP(Java Server Pages)で異なります。なお、動作環境は Tomcat を使用します。

・サーブレット
Tomcat ではデフォルトでサーブレットのレスポンスヘッダーに Content-Type を出力しません。ですので、以下のように自分で出力する必要があります。

resp.setContentType("text/html; charset=utf-8");

このサーブレットの Content-Type は以下のようになります
Content-Type:text/html;charset=utf-8

・JSP
Tomcat は JSP を表示する際、レスポンスヘッダーに Content-Type を UTF-8 でデフォルトで出力します(pageEncodingがutf-8の場合)。ですが、明示的に指定した方がよいでしょう。

JSP でレスポンスヘッダーに Content-Type を出力するには、Page ディレクティブで以下のように記述します。

<%@ page contentType="text/html; charset=utf-8" %>

この JSP の Content-Type は以下のようになります。
Content-Type:text/html;charset=utf-8

■2.HTML 要素の属性は""(ダブルクオーテーション)で囲む
これはそのままですが、HTML の属性は''(シングルクォーテーション)ではなく、""(ダブルクオーテーション)で囲むようにしてください。
<a href="https://www.websec-room.com/">Webセキュリティの小部屋</a>

■3.出力する全ての要素に対してエスケープ処理を行う
Java でエスケープ処理を行うために、org.apache.commons.text.StringEscapeUtils の StringEscapeUtils#escapeHtml4 メソッドを利用します。このメソッドは、&<>" をエスケープしてくれます。

なお、2の対策で HTML の属性を""(ダブルクオーテーション)で囲んでいるため、''(シングルクォーテーション)はエスケープの必須要件にはなりません。

・サーブレット

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.text.StringEscapeUtils;

public class XSS extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html; charset=utf-8");
    PrintWriter out = resp.getWriter();
    out.println("<html>");
    out.println("<body>");
    out.println(StringEscapeUtils.escapeHtml4("<script>alert('cookie'+document.cookie)</script>"));
    out.println("</body>");
    out.println("</html>");
    out.close();
  }
}

・JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="org.apache.commons.text.StringEscapeUtils" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<%=StringEscapeUtils.escapeHtml4("<script>alert('cookie'+document.cookie)</script>") %>
</body>
</html>

このサーブレットとJSPを表示しても、&<>"はエスケープされるためスクリプトは実行されません。

■4.URL は「http://」か「https://」で始まるもののみ出力する
URL 判定の実装例は以下のようになります。

public class XSS {
  public static boolean isUrl(String url) {
    if (url.matches("http://.*")
      || url.matches("https://.*")) {
      return true;
    } else {
      return false;
    }
  }
}

■5.<script></script> 要素の内容を動的に生成しない
これはそのままですね。

保険的対策

■1.入力値のチェックを行う
XSS で危険な文字である、&<>"' が文字列に含まれているか正規表現でチェックする実装例です。

public class XSS {
  public static boolean hasXssChars(String str) {
    if (str.matches(".*[<>&\"'].*")){
      return true;
    } else {
      return false;
    }
  }
}

■2.Cookie に HttpOnly 属性を付与する
Cookie に HttpOnly 属性を付与するには、サーブレットで以下のように記述します。
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class XSS extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html; charset=UTF-8");
    Cookie cookie = new Cookie("key", "value");
    cookie.setHttpOnly(true);  //HttpOnly属性付与
    resp.addCookie(cookie);
  }
}

なお、Tomcat のセッション ID に HttpOnly 属性と secure 属性を付与する方法は、以下の記事を参照してください。

■3.Trace メソッドを無効化する
Apache の Trace メソッドを無効にするには、httpd.conf に以下の行を追加し、Apache を再起動します。

TraceEnable Off

参考

Webアプリケーションセキュリティに関する記事は、以下のページにまとまっています。ぜひご確認ください。


スポンサーリンク





カテゴリー:Webアプリケーションセキュリティ対策

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA