http://example.com/Top.do;jsessionid=135383EED2F6BDFB50329A67DB1F4542 のように「;jsessionid=XXX」という文字列が付加されたURLを見たことはあるだろうか。
jsessionidとはJ2EEを使用したWebアプリケーションにおいてデフォルトで使用されるセッションIDを表すパラメータ名である。Servlet仕様では、セッションIDの格納先にCookieが利用できないクライアントが存在することを想定してURLへの文字列付加によるセッションIDの送信もサポートすることが推奨されている。
この仕様はURLリライティングと呼ばれ、
HttpServletResponse#encodeURL(String url)
および、
HttpServletResponse#encodeRedirectURL(String url)
により実装される。
Servlet仕様に従うならば、セッションIDがCookieによって送信されてこない場合は、画面遷移を行う際のURLにjsessionidを付加するよう実装することが必要である。
Strutsのタグライブラリを使用した場合、デフォルトではこの実装が暗黙的に行われるようサポートされている。例えば、以下のようなJSPを作成して、http://localhost:8080/WebAppSec/pages/session.jspというURLにアクセスした場合、初回のGETアクセス時と、画面内のリンクを押下して同一画面に遷移した際では異なるHTMLが生成される。
<%@page contentType="text/html; charset=Shift-JIS" pageEncoding="Shift_JIS" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html>
<head>
</head>
<body>
SessionIdは<%= session.getId() %>です<br>
<html:link page="/pages/session.jsp">自画面へ遷移する</html:link>
</body>
</html:html>
<html>
<head>
</head>
<body>
SessionIdは25379A23C5B3F3CAF868EC1AE0E337BBです<br>
<a href="/WebAppSec/pages/session.jsp;jsessionid=25379A23C5B3F3CAF868
EC1AE0E337BB ">自画面へ遷移する</a>
</body>
</html>
<html>
<head>
</head>
<body>
SessionIdは25379A23C5B3F3CAF868EC1AE0E337BBです<br>
<a href="/WebAppSec/pages/session.jsp">自画面へ遷移する</a>
</body>
</html>
生成されるHTMLが異なる理由は、初回アクセス時にはCookieが付加されずにリクエストが送信されるためである。初回アクセス時のレスポンスとして、Cookieが発行され、WebブラウザがCookieを受け入れた場合は、以降のアクセスにCookieが付加されたリクエストが送信される。リクエストにCookieが付加されていれば、URLにセッションIDを付加したレスポンスが生成されないためこのような挙動をする。
続いて、ログインページへ任意のセッションIDを付加したリクエスト発行のわなをしかける手順が踏まれた場合の挙動を見ていこう。
検証のために新しいWebブラウザを起動して、
http://localhost:8080/WebAppSec/pages/session.jsp;jsessionid=25379A23C5B3F3CAF868EC1AE0E337BB
へアクセスしてみる。
http://localhost:8080/WebAppSec/pages/session.jspへのアクセス時と違うのは、次画面への遷移のリンクを何回押下しても、URLへのセッションIDが外れないことだ。URLへ有効なセッションIDが付加されたリクエストが発行されてきた場合、新しくCookieが発行されることはなく、以降の遷移はURLにセッションIDが付加された形で行われる。従って、攻撃者が指定したセッションIDが以降のリクエストにも継続して使用されることになり、任意のセッションIDを付加したリクエスト発行のわなをしかけやすいことが分かるだろう。
Copyright © ITmedia, Inc. All Rights Reserved.