RedhatのStruts1脆弱性(CVE-2014-0114)対応 Part.1

RedhatからCVE-2014-0114の[セキュリティアップデート](https://rhn.redhat.com/errata/RHSA-2014-0474.html)が公開されたので調べてみた。

#調査対象
ftp://ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/SRPMS/struts-1.2.9-4jpp.8.el5_10.src.rpm

#ファイル一覧
SRPMの中身は以下のようになっている。

* struts-1.2.9-CVE-2014-0114.patch               
* struts-1.2.9-FacesRequestProcessor.patch
* struts-1.2.9-FacesTilesRequestProcessor.patch
* struts-1.2.9-HttpServletRequestWrapper.patch
* struts-1.2.9-src-RHCLEAN.tar.gz
* struts-1.2.9-strutsel-build_xml.patch    
* struts-1.2.9-strutsfaces-example1-build_xml.patch
* struts-1.2.9-strutsfaces-example2-build_xml.patch
* struts-1.2.9-strutsfaces-systest1-build_xml.patch
* struts-1.2.9.bz157205.patch
* struts.spec       
* tomcat4-context-allowlinking.xml
* tomcat5-context-allowlinking.xml

#脆弱性対応
上記のファイルで *struts-1.2.9-CVE-2014-0114.patch* が今回の脆弱性対応のパッチである。中身を見ると

```diff:struts-1.2.9-CVE-2014-0114.patch
diff -up ./src/share/org/apache/struts/util/RequestUtils.java.sav ./src/share/org/apache/struts/util/RequestUtils.java
--- ./src/share/org/apache/struts/util/RequestUtils.java.sav     2014-05-02 15:20:59.022457459 -0400
+++ ./src/share/org/apache/struts/util/RequestUtils.java     2014-05-02 15:22:15.669580263 -0400
@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
+import java.util.regex.Pattern;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -72,6 +73,12 @@ public class RequestUtils {
      */
     protected static Log log = LogFactory.getLog(RequestUtils.class);

+    /**
+     * <p>Pattern matching 'class' access.</p>
+     */
+    protected static final Pattern CLASS_ACCESS_PATTERN = Pattern
+            .compile("(.*\\\\.|^|.*|\\\\[('|\\"))class(\\\\.|('|\\")]|\\\\[).*",
+                    Pattern.CASE_INSENSITIVE);

     // --------------------------------------------------------- Public Methods

@@ -483,7 +490,8 @@ public class RequestUtils {

             // Populate parameters, except "standard" struts attributes
             // such as 'org.apache.struts.action.CANCEL'
-            if (!(stripped.startsWith("org.apache.struts."))) {
+            if (!(stripped.startsWith("org.apache.struts."))
+                    && !CLASS_ACCESS_PATTERN.matcher(stripped).matches()) {
                 properties.put(stripped, parameterValue);
             }
         }
```

上記のように *org.apache.struts.util.RequestUtils* に対する修正が行われている。 **CLASS_ACCESS_PATTERN** の正規表現は  *Struts2.3.16.2* で脆弱性対応として導入された[*ExcludedPatterns*](https://github.com/apache/struts/blob/STRUTS_2_3_16_2/xwork-core/src/main/java/com/opensymphony/xwork2/ExcludedPatterns.java)と同じものである。

この部分は *populate()* メソッドの前半部分で、この直後に以下のように問題となっている *BeanUtilis#populate()* の呼出が行われる。

```java:org.apache.struts.util.RequestUtils.java(抜粋)
try {
    BeanUtils.populate(bean, properties);
} catch(Exception e) {
    throw new ServletException("BeanUtils.populate", e);
} finally {
    if (multipartHandler != null) {
        ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
    }
}
```
ソース全体は[こちら](http://svn.apache.org/viewvc/struts/struts1/tags/STRUTS_1_2_9/src/share/org/apache/struts/util/RequestUtils.java?revision=418534&view=markup)を参照。

つまり、リクエストパラメータを *HashMap* に詰め込むときに問題となるパラメータを除外することで、*BeanUtils#populate()* の脆弱性を避けている。

Struts1の脆弱性対応は、いろいろ情報が錯綜しているが Redhat のようにきちんとセキュリティアップデートをソースと共に公開してくれるのはありがたい。

#参考
* [RedhatのStruts1脆弱性(CVE-2014-0114)対応 Part.2](http://qiita.com/ykare@github/items/4a9a1eebdb8a31dcdeb3)
* Redhat セキュリティアップデート https://rhn.redhat.com/errata/RHSA-2014-0474.html
* [S2-020類似攻撃のStruts1での対策方法](http://qiita.com/kawasima/items/670d2591bc8fea19dc1d)
* [自作のStruts1対策](https://gist.github.com/ykare/1fb2d5d11e16cb0003c3)