セキュアコーディング JavaにおけるXSS対策

些細な脆弱性が、システム全体を揺るがすことがある。XSS(クロスサイトスクリプティング)はその一例だ。ウェブの世界に潜む二枚刃の剣であり、気を抜いた瞬間に背後から襲いかかる。

1. XSS - たった1行のコードがシステムを危険に晒す

SQLインジェクションが「鍵泥棒」なら、XSSは「巧妙な詐欺師」だ。システムを直接攻撃するのではなく、ブラウザを欺いてユーザー自身に扉を開けさせる。 XSSは決して新しい問題ではない。ウェブの黎明期から潜んでおり、隙を見せると即座に攻撃を仕掛ける。OWASPは常にXSSを最も危険な脆弱性の一つとしてリストアップしており、たった1回のクリックでシステムが乗っ取られる危険性がある。

XSSの種類

Stored XSS(データベースに仕掛けられた時限爆弾)
悪意のあるスクリプトがデータベースに保存され、ユーザーがページを開いた瞬間に実行される。

Reflected XSS(目の前にある罠)
ユーザーがクリックしたURLに埋め込まれたスクリプトが即座に実行される。

DOM-Based XSS(フロントエンド内の攻撃者)
サーバーへのリクエストを必要とせず、ブラウザ内のJavaScript操作のみで実行される。

2. JavaにおけるXSS - 制御できないリスク
JSP、Servlet、Spring MVCを用いるJava Webアプリは、適切な入力チェックをしなければXSS攻撃を受けやすい。

JSPおよびJavaアプリにおけるXSSの例

2-1. JSPにおけるXSS
シンプルなコードに潜むリスク:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html>

      <head><title>ようこそ </title></head>

<body>

      <p>こんにちは、<%= request.getParameter("name") %></p>

</body>

</html>

以下のURLを開くと、スクリプトが実行される:

http://example.com/welcome.jsp?name=<script>alert('XSS Attack!')</script>

2-2. ServletにおけるXSS
Servlet内で適切なエスケープ処理をしないと、簡単にXSSが発生する。

@WebServlet("/greeting")

public class GreetingServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String name = request.getParameter("name");

        response.setContentType("text/html; charset=UTF-8");

        response.getWriter().println("<p>こんにちは、" + name + "</p>");

    }

}

URLに/greeting?name=<script>alert('XSS')</script>と入力すると、スクリプトが実行される。

2-3. Spring BootにおけるXSS
Spring Bootでも、不適切な処理をするとXSSが発生する。

@RestController
public class GreetingController { 
     @GetMapping("/greet")
     public String greet(@RequestParam String name) { 
         return "<p>こんにちは、" + name + "</p>";
     }
}


3. JavaにおけるXSS対策
3-1. 出力時のエスケープ処理
OWASP Java Encoderを使用してHTMLエスケープする。

<%@ page import="org.owasp.encoder.Encode" %>

<p>こんにちは、<%= Encode.forHtml(request.getParameter("name")) %></p>

3-2. 入力データの検証と制限
信頼できない文字列は制限する。
正規表現で制限をかける、またはサニタイズする。

public static boolean isValidInput(String input) {

     return input.matches("^[a-zA-Z0-9 ]*$");

}

3-3. Content Security Policy (CSP)の設定
外部スクリプトの実行を防ぐ。

Content-Security-Policy: default-src 'self'

3-4. Spring Securityでアプリを保護
Spring Securityのフィルタを活用してXSS攻撃を防ぐ。

4. XSSはJavaだけの問題ではない
XSS(クロスサイトスクリプティング)は、Javaだけでなく、PHPやJavaScriptなどの環境でも発生する脆弱性です。
例えば、PHPでは以下のようなコードがXSSを引き起こす可能性があります:

<?php

echo $_GET['name'];

?>

このコードでは、ユーザーからの入力を適切にエスケープせずに出力しているため、悪意のあるスクリプトが実行される可能性があります。
より詳細な情報については、以下のサイトが参考になります:
PHPを使ってWEBアプリケーションの脆弱性を確認する[クロスサイトスクリプティング(XSS)]
クロスサイトスクリプティング(XSS)とは?わかりやすく解説
クロスサイトスクリプティング(XSS)|影響と対策をわかりやすく解説

5. まとめ
XSSは単なるプログラミングミスではなく、セキュリティ意識の欠如が招く問題である。完璧なコードだけではなく、堅実なセキュリティ対策こそが安全なシステムを築く鍵となる。小さな隙が、大きな損害を生むことを忘れてはならない。

次回は「JavaにおけるSQLインジェクション対策」について解説します!