Webセキュリティの小部屋

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

セッション管理の不備と対策(Java編)

セッション管理の不備に対する根本的対策は、以下の記事を参照してください。

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

■1.推測困難なセッション ID を利用する
Java のセッション ID の生成は特に問題ないので、Java 実行環境のセッション ID 作成機能を利用します。

■2.セッション ID を URL に含めない
Java はデフォルトでセッション ID を URL に含みません。

■3.HTTPS 通信で利用する Cookie には secure 属性を付与する
Java で Cookie に secure 属性を付与するにはサーブレットで以下のように記述します。HttpOnly 属性も付与したほうがよいでしょう。

Cookie cookie = new Cookie("sample", "value");
cookie.setSecure(true);
cookie.setHttpOnly(true);
resp.addCookie(cookie);

レスポンスヘッダーには以下のように出力されます。
Set-Cookie: sample=value; Secure; HttpOnly

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

■4-1.ログイン後にセッションを新規に開始する
■4-2.ログイン後にセッション ID とは別の秘密情報を持ち、各ページでその値をチェックする
Java では 4-1 の方法を採用します。

Java で既存のセッションを破棄して、セッション ID を振り直し、新規セッションを開始するには、サーブレットで HttpSession#invalidate メソッドを実行後、HttpServletRequest#getSession メソッドを実行します。

下図の簡単なログイン機能で動作を確認します。

login

・login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
  <h1>ログイン</h1>

  <form action="/test/login" method="post">
    ID:<input type="text" name="id"><br>
    Password:<input type="password" name="password"><br>
    <input type="submit" value="ログイン">
    <input type="reset" value="リセット">
  </form>
</body>
</html>

・login(Login.java)
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Login extends HttpServlet {
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //パラメーター取得
    req.setCharacterEncoding("utf-8");
    String id = req.getParameter("id");
    String password = req.getParameter("password");

    //簡易ログイン
    if ("yamada".equals(id) && "pass".equals(password)) {
      //ログイン成功
      //セッション取得
      HttpSession session = req.getSession(true);

      //既存セッション破棄
      session.invalidate();

      //新規セッションを開始
      HttpSession newSession = req.getSession(true);

      //セッションに値を格納
      newSession.setAttribute("id", id);

      //リダイレクト
      resp.sendRedirect("/test/welcome.jsp");

    } else {
      //ログイン失敗
      //リダイレクト
      resp.sendRedirect("/test/login.jsp");
    }
  }
}

・welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="org.apache.commons.lang3.StringEscapeUtils" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>ようこそ、<%=StringEscapeUtils.escapeHtml4((String)session.getAttribute("id")) %>さん</h1>
</body>
</html>

login サーブレットのリクエストヘッダーは以下のようになります。

Referer: http://localhost:8080/test/login.jsp
Accept-Language: ja-JP
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 23
DNT: 1
Host: localhost:8080
Pragma: no-cache
Cookie: JSESSIONID=CE2D2BADBE5A674A2A281279A42305F7

レスポンスヘッダーは以下のようになっていて、セッションIDが振り直されていることが確認できます。
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=BE5CC69B118A713E5EC7F002EDC0BFA7; Path=/test/; HttpOnly
Location: http://localhost:8080/test/welcome.jsp
Content-Length: 0
Date: Sat, 09 Mar 2013 05:31:50 GMT

参考

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


スポンサーリンク





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

コメントを残す

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

CAPTCHA