今回のStruts1の脆弱性の問題は、どちらかというとcommons-beanutilsの問題な気がする。
commons-beanutilsはアクセス可能なプロパティは全て設定できてしまうのだが、使う側からすると自分が想定しているプロパティにのみ設定してほしいという要望はあるだろうし、commons-beanutilsの外でそのようなプロパティを除外するようにするとcommons-beanutilsの仕様が変化した時にうまくいかない。
例えば、Struts1だとActionFormを継承したクラスにフォームのパラメタを設定していくのだが、ActionFormやObjectクラスのプロパティを設定したいわけではない。
そういったことを考えるとライブラリ側にこのクラスより上のクラスのプロパティを対象外にするという指定が可能なメソッドを用意した方がセキュリティ的に良いと思う。しかし、commons-beanutilsもcommons-ognlも、現状そのような指定はできないようだ。
JavaのAPIレベルで考えるとjava.beans.Introspector#getBeanInfoでそのような指定が可能であるので、そのような実装はそれほど難しくないように思う。
getBeanInfo
public static BeanInfo getBeanInfo(Class<?> beanClass,
Class<?> stopClass)
throws IntrospectionExceptionJava Bean のイントロスペクションを行い、指定された「停止」ポイントに達するまで、プロパティー、公開されたメソッドを調べます。
この Java Bean の BeanInfo クラスに対して、同じ引数を使ってイントロスペクションを実行したことがある場合、BeanInfo キャッシュから BeanInfo クラスを取得できます。Introspector (Java Platform SE 7 )
- パラメータ:
beanClass
- 分析される Bean クラス。stopClass
- 分析を停止する基底クラス。stopClass またはその基底クラスに含まれるメソッド、プロパティー、イベントは、分析処理ではすべて無視される。- 例外:
IntrospectionException
- イントロスペクション中に例外が発生した場合。