公開日:2013年3月16日
最終更新日:2020年8月20日
最終更新日: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アプリケーションセキュリティ対策
コメントを残す