理系学生日記

おまえはいつまで学生気分なのか

MyFacesでのステートレスビューとCSRF対策の問題(解決済)

JSF において、ポストバックに対する CSRF 対策が実装されているというエントリを書きました。

ここでは、CSRF 対策トークンの値が javax.faces.ViewState という hidden 値に埋め込まれ、それを改竄した場合は ViewExpiredException が発生するという内容を記載しました。

ここで新しい話なのですが、MyFaces を使っているとき、この javax.faces.ViewState の値を stateless という値に変更(改竄) すると、何も例外もでないまま、処理が正常に行えるということがありました。 これは、JSF で導入されたステートレスビューによるものです。ステートレスビューについては、下記のエントリを参照して頂ければと思うのですが、ここでの問題は、

  • 外部から javax.faces.ViewState の値を操作するだけで、サーバ側をステートレスモードで動作させることができてしまう
  • ステートレスモードで動作させた場合は、コンポーネントビューの再構築が行われないので、CSRF 対策としても働かない

ということです。結果として、CSRF 攻撃が一定条件下では成立してしまいます。

すごく気になったので、1 週間ちかく調べていたのですが、どうも MyFaces の問題だったようで、そのものずばりの issue が MyFaces に挙がっていました。結構前に。

コミットは以下。transient="false" の Facelets を、外部から強制的にステートレスビューで動かそうとした場合はエラーとする対応のようです。

というわけで、いま最新版を取ればだいじょうぶなんじゃないかな。