12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

BeanUtils 1.9.2で追加されたSuppressPropertiesBeanIntrospectorの使い方

Posted at

Struts1の脆弱性問題で、commons-beanutilsに対応が入ったバージョン1.9.2がリリースされました。
https://issues.apache.org/jira/browse/BEANUTILS-463

といっても、デフォルトで問題が修正されるわけではなく、セットアップは必要です。

仕組み

BeanIntrospectorという仕組みが1.9.xからは導入されていて、PropertyUtilsにこのBeanIntrospectorを追加すると、オブジェクトのどのメソッドをプロパティとして扱うかの挙動を変えることができるようになっています。

使い方はテストコードがあるので、そちらを見てみます。

String[] properties = { "test", "other", "oneMore" };
SuppressPropertiesBeanIntrospector introspector = new SuppressPropertiesBeanIntrospector(
                Arrays.asList(properties));

単にプロパティとして扱いたくないものの名前をコンストラクタで渡すだけです。

getClassをプロパティとして扱わないようにする

さて、Struts1の脆弱性の原因であったこの問題に対処してみます。SuppressPropertiesBeanItrospectorに専用のSUPPRESS_CLASSがあるので、これをPropertyUtilsのaddIntrospectorに渡すだけです。

Map<String, String> desc1 = BeanUtils.describe(new TestBean());
assertNotNull(desc1.get("class"));
BeanUtils.getProperty(new TestBean(), "class");
                                                                             
PropertyUtils.addBeanIntrospector(                                   
    SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);          
PropertyUtils.clearDescriptors();                                    
                                                                             
Map<String, String> desc2 = BeanUtils.describe(new TestBean());      
assertNull(desc2.get("class"));                                      
try {                                                                
    BeanUtils.getProperty(new TestBean(), "class");                  
    fail("Could access class property");                             
} catch(NoSuchMethodException ex) {
     // ok
}                                                                    
    }                                                                        

これで、classがプロパティ扱いされなくなります。populateもdescribeもgetProperty/setPropertyもOKです。

Webアプリで使うときは、Resolverでの対処と同じように、ServletListenerに入れ込めばよいです。

package example;
 
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
 
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.SuppressPropertiesBeanIntrospector;

public class SuppressPropertiesListener implements ServletContextListener {
 
    @Override
    public void contextInitialized(ServletContextEvent event) {
        PropertyUtils.addBeanIntrospector(
            SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);
        PropertyUtils.clearDescriptors();
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent event) {
    }
}

本家の公式なので、まぁ一番キレイに対応できますね。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?