Servletプログラミングでセッションを使うとき、Cookieをクリアしたブラウザでアクセスすると初回のPOSTやGET遷移でだけ、URLに";jsessionid=xxxxyyyy..."というのが付加される。
以前から、これはServletコンテナが独自に実装してくれた機能なのか、Servletの仕様としてそうなっているのかが気になっていた。先日お仕事中にその辺りを調べる必要が生じたので、数年越しに自分の中でこの";jsessionid=xxxxyyyy..."について決着をつける。
JSESSIONIDや";jsessionid="がどこで定められているのかというと、Servletの仕様で定められています。
これらはJSRとして入手・参照可能です。
以下に簡単に主なバージョンとリリース年月についてまとめます。Version 2.3以降のリリース年月についてはJSR上での"Start"を元にしています。
Version 1.0 | 1997-06 by Sun Microsystems |
Version 2.3 | 2001-09 Final Release Start, JSR53 (Java Community PRocess, with JSP 1.2 Specs) |
Version 2.4 | 2003-11 Final Release Start, JSR154 |
Version 2.5 | 2007-09 Maintenance Release 2 Start, JSR154 |
Version 3.0 | 2009-12 Final Release Start, JSR315 |
今回主に取り上げるTomcat6, Jetty7で対応しているServlet 2.5の仕様を確認すると、"SRV.7.1 Session Tracking Mechanisms"で以下のように記されています。
SRV.7.1.1 Cookies
Session tracking through HTTP cookies is the most used session tracking mechanism and is required to be supported by all servlet containers.
The container sends a cookie to the client. The client will then return the cookie on each subsequent request to the server, unambiguously associating the request with a session. The name of the session tracking cookie must be JSESSIONID.
(...)
SRV.7.1.3 URL Rewriting
URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basisfor session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.
The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:
http://www.myserver.com/catalog/index.html;jsessionid=1234
JSESSIONIDについては"must be"、つまりセッション維持のCookieの名前はJSESSIONID「でなければならない」となっています。また";jsessionid="についても"must be"で同様となっています。
もちろん後で確認するようにTomcatやJettyなど実際のServletコンテナでは、設定によってこれらを変更することも可能となっています。
クライアントがCookieを使えない場合ですが、"When a client will not accept a cookie, URL rewritingmay be usedby the server as the basisfor session tracking."とあります。ですので厳密にはURL Rewritingは使わなくても良いと考えられ、実際に後で確認するようにTomcat 6.0.30以上やJetty7ではURL Rewritingの無効化が設定可能です。
とはいえ、以下のようにCookieが使えないHTTPクライアントもサポートする必要があると定められていることからURL Rewritingによるセッション維持は必須の機能となっているようです。
SRV.7.1.4 Session Integrity
Web containers must be able to support the HTTP session while servicing HTTP requests from clients that do not support the use of cookies. To fulfill this requirement, Web containers commonly support the URL rewriting mechanism.
Servlet 3.0では、JSESSIONIDやURL Rewritingについて以下の変更がされています。
簡単に原文を紹介して終わりにします。
7.1.1 Cookies
Session tracking through HTTP cookies is the most used session tracking mechanism and is required to be supported by all servlet containers.
The container sends a cookie to the client. The client will then return the cookie on each subsequent request to the server, unambiguously associating the request with a session. The standard name of the session tracking cookie must be JSESSIONID, which must be supported by all 3.0 compliant containers. Containers may allow the name of the session tracking cookie to be customized through container specific configuration.
All servlet containers MUST provide an ability to configure whether or not the container marks the session tracking cookie as HttpOnly. The established configuration must apply to all contexts for which a context specific configuration has not been established (see SessionCookieConfig javadoc for more details).
If a web application configures a custom name for its session tracking cookies, the same custom name will also be used as the name of the URI parameter if the session id is encoded in the URL (provided that URL rewriting has been enabled).
(...)
7.1.3 URL Rewriting
URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basis for session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.
The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:
http://www.myserver.com/catalog/index.html;jsessionid=1234
URL rewriting exposes session identifiers in logs, bookmarks, referer headers, cached HTML, and the URL bar. URL rewriting should not be used as a session tracking mechanism where cookies or SSL sessions are supported and suitable.
URLでセッションIDを指定できる状態だと、セッション固定化の問題やURLからのセッションID漏えいの問題が発生します。
PC/スマホ向けのServletアプリは基本的にはCookieでセッションを管理していると思います。その場合、URLからのセッションID漏えいの問題の影響は無いと考えられます。
しかしServletの仕様によりURLからもセッションIDを受け入れてしまう状態であれば、セッション固定化の問題を考える必要があります。セッション固定化では攻撃者が用意したセッションIDを被害者に使わせ、被害者にログインさせるなどして攻撃者はセッション情報を入手しなりすまし等に悪用します。URLからセッションIDを指定できるということは、攻撃者が用意したセッションID付きのURLに被害者を誘導し、ログインなどの操作を行わせることが可能です。セッション固定化を悪用するための入り口の一つになってしまうことが考えられます。もちろん、セッション固定化の対策がきちんとされていれば、URLからセッションIDを指定できても問題にはつながらないと考えられます。
この点については最後のまとめで考えてみました。
TomcatとJettyについて、Cookieを無効にした状態でアクセスし、初期状態でURL-Rewritingによるセッション管理が有効となるか確認してみます。
今回はTomcat 6.0.35に含まれている"examples"アプリのSessionのサンプルを使って、JSESSIONIDや";jsessionid=" URL Rewritingの動作を確認してみました。
Tomcat6系はServlet 2.5を実装していますので、基本的にはJSESSIONID + ";jsessionid"によるURL Rewritingが有効化されています。しかし設定によりWebアプリごとにJSESSIONIDの名前を変更できます。また、Tomcat 6.0.30 以上であれば、URL Rewritingを無効化したりすることが可能です。
JavaEE/Servlet/対応したTomcatのバージョンをまとめておきます。
JavaEE6 | Servlet 3.0, JSP2.2 | Tomcat 7以上 |
JavaEE5 | Servlet 2.5, JSP 2.1 | Tomcat 6以上 |
J2EE 1.4 | Servlet 2.4, JSP 2.0 | Tomcat 5.x, 5.5.x以上 |
J2EE 1.3 | Servlet 2.3 JSP 1.2 | Tomcat 4.x |
デフォルト状態では"examples"で特にsession関連の設定は行われておりません。Tomcatであれば"conf/Catalina/<hostname>/"以下の"<Context名>.xml"でWebアプリごとのコンテキスト設定を行えますが、デフォルトでは"examples"アプリ用の設定ファイルはありません。
この状態で、Burpを使って常にリクエストからCookieヘッダーを除去するようにしたProxyを通してアクセスします。
まずテストアプリのSessionサンプルは以下のURLでアクセスできました。
http://localhost:8080/examples/servlets/servlet/SessionExample
すると以下の様なレスポンスを受信しました。
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=6B9DBEF80A2B62BC04E80FD73E7B14CA; Path=/examples Content-Type: text/html Content-Length: 1270 Date: Sun, 17 Jun 2012 09:03:22 GMT <html> ... <form action="SessionExample;jsessionid=6B9DBEF80A2B62BC04E80FD73E7B14CA" method=POST>
JSESSIONID Cookieが発行され、また"<form>"のaction属性に";jsessionid="が埋め込まれていることが確認されます。
BurpによりブラウザからのCookieヘッダを削除した状態でそのままサンプルアプリを操作してみると、";jsessionid="だけで正常にサンプルアプリを操作できることが確認されました
conf/Catalina/localhost/examples.xmlを以下の内容で保存します。
<?xml version="1.0" encoding="UTF-8"?> <Context disableURLRewriting="true" sessionCookieName="MYSESSID" />
セッションのCookie名に"MYSESSID"を指定し、6.0.30以降で指定可能になった"disableURLRewriting"でURL Rewritingを無効化します。
Tomcatによりコンテキストがリロードされた後、以下のURLにアクセスしました。
http://localhost:8080/examples/servlets/servlet/SessionExample
CookieもBurpにより削除され、URLにも指定されていないため以下のようなレスポンスを受信しました。
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: MYSESSID=3C117B729074A4EF6A3C38127E5E1D1E; Path=/examples; HttpOnly Content-Type: text/html Content-Length: 1138 Date: Sun, 17 Jun 2012 09:19:31 GMT <html> ... <form action="SessionExample" method=POST>
"Set-Cookie"で発行されるCookie名がXMLで指定した MYSESSID" になっています。また、先ほどと違い、"<form>"要素の"action"属性のURLに";jsessionid="がありません。
このままBurpによりCookieが削除される設定で操作をすると、毎回Set-Cookieされるため、セッション情報の変更などサンプルアプリの一部の機能が動かなくなりました。
なお"disableURLRewriting"はTomcat6系の、6.0.30以降でのみ使えます。Tomcat5系、Tomcat 6.0.29以前、Tomcat7系では使えません。Tomcat7系であればServlet 3.0に対応していますので、web.xmlによりCookieのみ+URL Rewriting無しを指定できます。
Javaのシステムプロパティを使うことで、Tomcat全体でセッションCookie名を変更できます。但しこれはアプリごとのContext設定を上書きしてしまいますので、実用上のメリットは薄いかもしれません。
Sessions
org.apache.catalina.SESSION_COOKIE_NAME
An alternative name for the session cookie. Defaults to JSESSIONID. Note that the Servlet specification requires this to be JSESSIONID. You should not rely on being able to change this.
org.apache.catalina.SESSION_PARAMETER_NAME
An alternative name for the session path parameter. Defaults to jsessionid. Note that the Servlet specification requires this to be jsessionid. You should not rely on being able to change this.
Tomcat7系ではServlet 3.0が実装されました。その結果、Servlet 3.0の仕様としてweb.xmlにセッション維持の方法を明示できるようになりました。その影響として、disableURLRewritingは不要とされTomcat7のContext設定では実装されていません。
Servlet 3.0ではセッション維持の方法にCookieのみを用いる場合、web.xmlに以下の記述を追加します。
<session-config> <tracking-mode>COOKIE</tracking-mode> </session-config>
"<tracking-mode>"には他にも"URL"と"SSL"を組み合わせて指定可能なようです。
参考:
既にTomcat6.0系では検証記事がありますが、自分でも確認してみました。
結果(Tomcat 6.0.35):
デフォルト状態:disableURLRewriting指定なし(=有効) | Cookie優先 |
disableURLRewriting="true" | Cookie優先 |
結果(Tomcat 7.0.16):
デフォルト状態:<tracking-mode>指定なし | Cookie優先 |
<tracking-mode>COOKIE</tracking-mode>のみ指定 | Cookie優先 |
リクエスト-レスポンス例(上記4パターン全てで同じ挙動):
[request] GET /examples/servlets/servlet/SessionExample;jsessionid=CA3FABDC2A12AF2CA7F33AEABF13280D HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Cookie: JSESSIONID=BFC3212F70EE1BB1D88B9AF9077FC0F7 ;;BFC3...が自分のブラウザに発行されたセッションID ;;CA3F...が別ブラウザに発行されたセッションID [response] HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/html Content-Length: 1170 Date: Sun, 17 Jun 2012 09:43:10 GMT <html> ... <h3>Sessions Example</h3> Session ID: BFC3212F70EE1BB1D88B9AF9077FC0F7
→";jsessionid="で指定されたセッションIDは無視され、Cookieで送信したセッションIDが使われていることが確認されました。
このように既にCookieがセットされた状態であればURLではなくCookieの値をセッションIDとして使います。ではCookieが空、つまりそのサイトに初回アクセスしたり、ログアウトされてセッションがクリアされた状態で";jsessionid="付きのURLにアクセスするとどうなるかというと、URL Rewriting ON/OFFに応じて以下のようになります。
Tomcat 6.0.35では";jsessionid="指定されたCookieをそのまま受け入れてしまっています。これは、"disableURLRewriting"はあくまでも「URLのRewriting」の設定であってセッション維持の方法の指定ではない=";jsessionid="で指定された値が受け入れられる挙動には影響しない、ということが想像されます。
一方でTomcat7のServlet 3.0での"<tracking-mode>"はURL Rewritingだけでなくセッション維持の方法そのものを指定しているため、COOKIEとした場合Cookieのみが受け入れられ、";jsessionid="の指定は無視されているということが想像されます。
今回は jetty-hightide-7.6.4.v20120524 を使って、Jettyに最初から含まれているtest.war中のSessionサンプルプログラムの動作を確認してみました。
Jetty-7系はServlet 2.5を実装していますので、基本的にはJSESSIONID + ";jsessionid"によるURL Rewritingが有効化されています。しかし設定によりWebアプリごとにJSESSIONIDの名前を変更できたり、URL Rewritingを無効化したりすることが可能です。
contexts/test.xml ではデフォルトでは特にsession関連の設定は行われていません。以下がコメントアウトされているだけです。
<!-- disable cookies <Get name="sessionHandler"> <Get name="sessionManager"> <Set name="usingCookies" type="boolean">false</Set> </Get> </Get> -->
この状態で、Burpを使って常にリクエストからCookieヘッダーを除去するようにしたProxyを通してアクセスします。
まずテストアプリのSessionサンプルは以下のURLでアクセスできました。
http://localhost:8080/test/session/
"No Session"と表示され、"New Session"というボタンが表示されているのでクリックすると以下のような302リダイレクトレスポンスを受信しました。
HTTP/1.1 302 Found Date: Sun, 17 Jun 2012 07:43:15 GMT Set-Cookie: JSESSIONID=spzyfhy235vg562pm2yeydof;Path=/test Expires: Thu, 01 Jan 1970 00:00:00 GMT Location: http://localhost:8080/test/session/;jsessionid=spzyfhy235vg562pm2yeydof?R=1 Content-Length: 0 Server: Jetty(7.6.4.v20120524)
JSESSIONID Cookieが発行され、さらにLocationでは";jsessinid="によりURLでセッションIDを指定するURLにリダイレクトさせています。
ブラウザはLocationで指定されたURLに遷移しますが、この時、BurpによりCookieヘッダーを削除したリクエストがサーバに送信されました。
GET /test/session/;jsessionid=spzyfhy235vg562pm2yeydof?R=1 HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Referer: http://localhost:8080/test/session/
その結果、レスポンスHTML中の"<form>"タグは以下のようにURL Rewritingされたaction属性がセットされました。
<h1>Session Dump Servlet:</h1> <form action="/test/session/;jsessionid=spzyfhy235vg562pm2yeydof" method="post"> <b>ID:</b> spzyfhy235vg562pm2yeydof<br/> ...
そのままサンプルプログラムの機能としてセッションへのNameとValueペアの追加や更新、削除が正常に実行できました。
contexts/test.xmlに以下の設定を追加してみます。(上書き保存すると自動的にコンテキストがリロードされます)
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> ... <Get name="sessionHandler"> <Set name="sessionManager"> <New class="org.eclipse.jetty.server.session.HashSessionManager"> <Set name="sessionCookie">MYSESSID</Set> <Set name="sessionIdPathParameterName">none</Set> </New> </Set> </Get> ... </Configure>
sessionIdPathParameterName に "none" を指定することで、";jsessionid="のURL Rewritingが無効化されます。
コンテキストがリロードされた後、以下のURLにアクセスしました。
http://localhost:8080/test/session/
CookieはBurpにより削除され、URLにも指定されていないので、以下のような"No Session"レスポンスを受信しました。
<h1>Session Dump Servlet:</h1> <form action="/test/session/" method="post"> <H3>No Session</H3> <input type="submit" name="Action" value="New Session"/>
"New Session"ボタンをクリックすると、以下の302リダイレクトレスポンスを受信しました。
HTTP/1.1 302 Found Date: Sun, 17 Jun 2012 07:56:52 GMT Set-Cookie: MYSESSID=1lj1lzunafwtim2g5gy0wsrkd;Path=/test Expires: Thu, 01 Jan 1970 00:00:00 GMT Location: http://localhost:8080/test/session/?R=0 Content-Length: 0 Server: Jetty(7.6.4.v20120524)
"Set-Cookie"で発行されるCookie名がXMLで指定した MYSESSID" になっています。また、先ほどと違い、Locationのりダイレクト先に";jsessionid="がありません。
ブラウザはLocationで指定されたURLに遷移しますが、途中のBurpによりCookieヘッダが削除されたリクエストがJettyに送信されました。その結果、セッションが無いものとServlet側では認識され、再度"No Session"レスポンスを受信しました。
Tomcat6(Servlet 2.5)の比較としてjetty-hightide-7.6.4.v20120524について確認してみました。
先に結論ですが、jettyの場合は <Set name="sessionIdPathParameterName">none</Set> を指定することでServlet側は";jsessionid="で指定された値を無視します。但しURL Rewriteについては";jsessionid="で指定された値が使われるため、CookieとURL Rewriteされる値がチグハグな状態になります。
1. jetty-hightide-7.6.4.v20120524, <Set name="sessionIdPathParameterName">none</Set>
1-a. Cookie + ";jsessionid="両方を指定
GET /test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172 HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Cookie: JSESSIONID=1xxlrptfiimi2iw5spo1kueas HTTP/1.1 200 OK Date: Sun, 17 Jun 2012 10:47:51 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 1068 Server: Jetty(7.6.4.v20120524) <h1>Session Dump Servlet:</h1> <form action="/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172" method="post"> <b>ID:</b> 1xxlrptfiimi2iw5spo1kueas<br/> ...
→ServletにはCookieで送信した値が受け入れられているが、URL Rewritingで使われているのは";jsessionid="で指定した値。
1-b. Cookie削除, ";jsessionid="のみを指定
GET /test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172 HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive HTTP/1.1 200 OK Date: Sun, 17 Jun 2012 10:48:08 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 193 Server: Jetty(7.6.4.v20120524) <h1>Session Dump Servlet:</h1> <form action="/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172" method="post"> <H3>No Session</H3> <input type="submit" name="Action" value="New Session"/>
→"No Session"と判定されているが、"<form>"要素の"action"属性には";jsessionid="で指定した値でそのままURL RewriteされたURLが埋め込まれています。なお、このまま"New Session"をクリックすると以下のようになります(Burpにより強制的にCookieを削除して送っています):
POST /test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172 HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Referer: http://localhost:8080/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=4 Content-Type: application/x-www-form-urlencoded Content-Length: 18 Action=New+Session HTTP/1.1 302 Found Date: Sun, 17 Jun 2012 10:53:24 GMT Set-Cookie: JSESSIONID=1c69qt9s3qjnr1s2s0ez300q;Path=/test Expires: Thu, 01 Jan 1970 00:00:00 GMT Location: http://localhost:8080/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=5 Content-Length: 0 Server: Jetty(7.6.4.v20120524) GET /test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=5 HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Referer: http://localhost:8080/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=4 HTTP/1.1 200 OK Date: Sun, 17 Jun 2012 10:53:25 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 193 Server: Jetty(7.6.4.v20120524) <h1>Session Dump Servlet:</h1> <form action="/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172" method="post"> <H3>No Session</H3> <input type="submit" name="Action" value="New Session"/>
ここでCookieを有効にしてもう一度"New Session"をクリックします。
HTTP/1.1 302 Found Date: Sun, 17 Jun 2012 10:53:53 GMT Set-Cookie: JSESSIONID=k2jt9gwim4t09qyip8hmbxu6;Path=/test Expires: Thu, 01 Jan 1970 00:00:00 GMT Location: http://localhost:8080/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=6 Content-Length: 0 Server: Jetty(7.6.4.v20120524) GET /test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=6 HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Referer: http://localhost:8080/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172?R=5 Cookie: JSESSIONID=k2jt9gwim4t09qyip8hmbxu6 HTTP/1.1 200 OK Date: Sun, 17 Jun 2012 10:53:54 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 1043 Server: Jetty(7.6.4.v20120524) <h1>Session Dump Servlet:</h1> <form action="/test/session/;jsessionid=wzf5bjy9k3kxqjif7faaj172" method="post"> <b>ID:</b> k2jt9gwim4t09qyip8hmbxu6<br/> ...
結論から言うと、Jetty7で<Set name="sessionIdPathParameterName">none</Set>とした場合、URL Rewritingに使われるのは";jsessionid="で指定された値であるものの、実際にServletが処理で使っているのはCookieの値となります。
2. jetty-hightide-7.6.4.v20120524, デフォルト
2-a. Cookie + ";jsessionid="両方を指定
GET /test/session/;jsessionid=ku2aqgtv6zefbk4on821ebaa HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Cookie: JSESSIONID=1hkvypdmvxe5wrmgbf8zz3fqz HTTP/1.1 200 OK Date: Sun, 17 Jun 2012 11:02:18 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 997 Server: Jetty(7.6.4.v20120524) <h1>Session Dump Servlet:</h1> <form action="/test/session/" method="post"> <b>ID:</b> 1hkvypdmvxe5wrmgbf8zz3fqz<br/>
→";jsessionid="で指定した値は完全に無視され、"<form>"要素の"action"属性もURL Rewriteされていません。
2-b. Cookie削除, ";jsessionid="のみを指定
GET /test/session/;jsessionid=ku2aqgtv6zefbk4on821ebaa HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive HTTP/1.1 200 OK Date: Sun, 17 Jun 2012 11:04:25 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 1070 Server: Jetty(7.6.4.v20120524) <h1>Session Dump Servlet:</h1> <form action="/test/session/;jsessionid=ku2aqgtv6zefbk4on821ebaa" method="post"> <b>ID:</b> ku2aqgtv6zefbk4on821ebaa<br/> ...
→Servlet側で";jsessionid="で指定された値を受け入れ、さらにURL Rewritingでも使っていることが確認されました。
もし完全にセッションIDを制御下に置きたいのであれば、ServletコンテナすなわちServletの仕様で提供されているセッション機構を使うのでなく、独自のセッション管理機構を開発した方が良いのかもしれません・・・。
他、参考になったURL:
あとがき:
OWASPとかWASCも調べてみたんですが、Servletの";jsessionid="の記事が見つかりませんでした。Session管理系の話題でもスルーされているようです。
とまれ、数年来の疑問が解決しましたので気分的にはすっきりしました。
LL言語であれば変数のシリアライズが比較的簡単に出来るので、独自のセッション機構を開発するのは割りと敷居が低いのですが、Java Servletとなりますと、特にレプリケーションなどで複数インスタンス間で同期を取ることを考えるとJavaオブジェクトのSerializeをしなければなりませんので大変そうです。Servletコンテナの1インスタンス内で完結するのであれば他にやり用はあるかもしれませんが・・・。
コメント