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 を、外部から強制的にステートレスビューで動かそうとした場合はエラーとする対応のようです。
というわけで、いま最新版を取ればだいじょうぶなんじゃないかな。