ひがやすを技術ブログ

電通国際情報サービスのプログラマ

StrutsのClassLoader脆弱性はSAStrutsに影響しません

Struts2に見つかった脆弱性と同様の脆弱性がStruts1系にも見つかりました。
Apache Struts 2の脆弱性が、サポート終了のApache Struts 1にも影響


HTTP(S)のリクエストでJavaのClassLoaderのメソッドが呼び出せてしまうという脆弱性です。


もう少し噛み砕いて言えば、リクエストのパラメータをJavaBeansにセットする時に、リフレクションを使い、パラメータ名にaaa.bbb.cccのようなネストした名前をサポートしているフレームワークは同様の問題が起こる可能性があります。
パラメータ名をclass.classLoader.xxxのような感じにして、ClassLoaderのメソッドを呼び出す訳です。


このような問題を起こすリフレクションフレームワークで最も有名なのは、Apache Commons BeanUtilsです。リクエストのパラメータをBeanUtilsを使って、JavaBeansにセットしているフレームワークは、Strutsに限らず同じことが起きると思います。


SAStrutsは、リクエストパラメータをJavaBeansにセットするのに、BeanDescという独自フレームワークを使っていて、BeanDescはclassプロパティにアクセスできないようになっているので大丈夫です。
これは、小林さんがTwitterで言っている通りです。
https://twitter.com/koichik/status/459277890824052736


Seasar2系のWebフレームワークで、リクエストパラメータをJavaBeansにセットするのに、BeanDescを使っているなら、SAStrutsと同様に大丈夫です。独自もしくは、BeanUtilsを使っているWebフレームワークは、至急確認をしてください。


リクエストパラメータをJavaBeansにセットするのに、BeanUtilsではなく、OGNLを使っているプロジェクトも危険です(だと思う)。これが元々Struts2で指摘されていた問題です。

JavaBeansに対するリフレクションとClassLoader脆弱性

今回の問題は、(SA)Strutsだけの問題ではなく、いろんなフレームワークでもちゃんと調べた方が良い話しなので、もう少し詳しく書いておきます。


Javaで、JavaBeansのプロパティにアクセスする場合、


PropertyDescriptor[] descriptors = Introspector.getBeanInfo(クラス).getPropertyDescriptors();
で取得できるPropertyDescriptorを使うことがほとんどです。この中に、classプロパティは含まれます。
ここまでは良くて、ネストしたリクエストパラメータ(class.classLoader.xxxなど)をJavaBeansにセットする時に、BeanInfo.getPropertyDescriptors()で取得したものをそのまま使うのが問題なのです。


Seasar2(BeanDesc)では、classプロパティとObjectのプロパティは除外してます。
Seasar2に対応したフレームワークで、HOT deployをサポートしているフレームワークは、まちがいなくBeanDescを使っています。標準のjava.beans.Introspectorを使うとHOT deployがうまく行かないからです。
なので、TeedaS2JSFなども大丈夫。S2Strutsは追記の方に書いてあります。


commons BeanUtilsを使っている場合は、今回の問題が発生するので、BeanUtilsにパッチを当てて、classプロパティとObjectのプロパティを対象外にするのが、根本的な対応だと思います(自分ならそうします)。
パラメータ名を正規表現ではじくだとかは、Objectのプロパティが将来的に増えた時に、ちょっと心配。


commons BeanUtils以外では、SpringにもBeanUtilsというクラスがあったと思うので、Springな人は、チェックしましょう。


追記:BeanUtilsレベルでは、Objectのプロパティにアクセスできても良いんじゃないかという意見ももっともですが、"aaa.bbb.ccc"のようなある種の式言語でObjectのプロパティにアクセスできると今回のようなセキュリティーホールが発生するリスクがあるので、BeanUtilsレベルで止めていた方が安全じゃないかなと思います。セキュリティーの話しなので、固い方に振っておいた方が良いという意味。
追記2:S2Strutsは、1.2はアウト。1.3はまだ、調べ中です。
追記3:S2Struts 1.3はPOJO ActionはOK、POJO ActionFormはNGです。
追記4:さらに懸賞の結果、S2Strutsは1.2も1.3もPOJO ActionはOK、POJO ActionFormはNGでした。