クッキーとセッション管理の理解を深める
はじめに
Webアプリケーションのセキュリティを学んでいく中で、クッキーとセッションの理解が曖昧な部分があると感じたので下記を参考に学習をしてみました。
クッキー(cookie)とセッションとは
まず、具体的な使用例としては下記のようなものが挙げれます。
- ログインした後で、ログインの有無の判定やログインユーザーの名前を保持したい。
- ECサイトでどのユーザーがどの商品をショッピングカートに入れているか判断したい。
上記を実現するためにクッキーとセッションを用いるわけですが、上記のようにアプリケーションの状態や一連の流れを管理することをセッション管理と言います。
このセッション管理をHTTPで実現する目的でクッキーという仕組みが導入されました。クッキーは、サーバー側からブラウザに対して、「名前=変数」の形式で覚えておくように指示するものです。クッキーはセッション管理という機能の実現に使われます。
認証にクッキーとセッションを使用する例
下記では、Javaを例にログイン画面 → ログイン後のメニュー画面と
ログイン時のPOSTメソッドの処理(抜粋版)
ログイン後のGETメソッドの処理(抜粋版)を示しています。
↓↓↓
/** POST: IDセッション保存→リダイレクト */
req.setCharacterEncoding("UTF-8");
String id = req.getParameter("ID");
String pwd = req.getParameter("PWD");
// 入力が空の場合はログイン失敗
if (id == null || id.isEmpty() || pwd == null || pwd.isEmpty()) {
resp.setContentType("text/plain; charset=UTF-8");
resp.getWriter().println("ログイン失敗");
return;
}
//セッションに保存
HttpSession session = req.getSession(true);
session.setAttribute("ID", id);
// menu画面へ
resp.sendRedirect(req.getContextPath() + "/menu");
/** GET: IDセッション取得→画面表示 */
HttpSession session = req.getSession(false);
String id = (session != null) ? (String) session.getAttribute("ID") : null;
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("""
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"></head>
<body>
ログインID:%s
</body>
</html>
""".formatted(StringEscapeUtils.escapeHtml4(id)));
ログイン時にIDとパスを入力して、POSTメソッドを実行すると、以下のようにCookieの情報がサーバーに送信されます。
cookie
JSESSIONID=F6F5AAEA8BA4F680A5125900B6908A46
また、レスポンスヘッダの「Set-Cookie」により、Webサーバーはブラウザに対してクッキー値を覚えるように指示します。
set-cookie
JSESSIONID=00AA6D4CAD7B9DDBE54583E1C9B178F8; Path=/; HttpOnly
JSESSIONIDのクッキー値はセッションIDと呼ばれ、セッション情報にアクセスするためのキー情報となるものです。
ログイン時に session.setAttribute("ID", id);でログインIDをセッション変数に格納して、ログイン後のメニュー画面でsession.getAttribute("ID")を使って、ログインIDを取り出しています。セッション変数に格納された情報は、セッションが有効である限りいつでもアクセス可能です。
セッション管理の不備・セッションIDの漏洩
クッキーはデータをブラウザ側で覚えておけるものですが、アプリのデータを保持・管理する目的でクッキーに値を入れることは推奨できません。
・クッキーが保持できる値の個数や文字列長には制限がある
・クッキーの値は利用者本人には参照・変更できるので、秘密情報の格納には向かない
という理由があるからです。
そのため、クッキーにはラベルとしてのセッションIDを格納しておき、実際の値はサーバー側で管理する方法が広く用いられます。
そのセッションIDが他者に知られたりすると成りすましができてしまいます。そのため、下記のようにセッションIDを作成・管理する際には下記の要件を満たす必要があります。
1:第三者がセッションIDを推測できないこと
2:第三者からセッションIDを強制されないこと
3:第三者にセッションIDが漏洩しないこと
上記の要件についてはIPAの安全なウェブサイトの作り方 1.4 セッション管理の不備に詳しく対策方法が書いてあるので参考にしてください。
まとめ
クッキーやセッション管理は認証情報を保存したり、アプリケーションを構築する上で便利な機能として利用できますが、脆弱性を孕む原因にもなり得るので正しい知識を見つけて利用していきたいと思います。
Discussion