LoginSignup
5
7

More than 5 years have passed since last update.

サーブレット・フィルタによるApache Struts2の脆弱性(S2-016)への対応

Last updated at Posted at 2013-07-31

Apache Struts の脆弱性 (S2-016) に関する注意喚起に対して、struts2のバージョンアップをするのが最善ですが、何らかの事情によりバージョンアップが難しい場合の対応策の一つとして、サーブレット・フィルタによる防御があります。

サーブレット・フィルタのコード

AttackURLParamBlockFilter.java
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain filter) throws IOException, ServletException {
        Enumeration<?> params = req.getParameterNames();

        while (params.hasMoreElements()) {
            String paramName = (String) params.nextElement();
            String paramValue = req.getParameter(paramName);

            if (isSafetyParam(paramName, paramValue)) {
                continue;
            }
            throw new IllegalArgumentException(
                    String.format(
                            "Bad request '%s' was detected.\n",
                            paramName, paramValue));
        }

        filter.doFilter(req, res);
    }

    private static boolean isSafetyParam(String name, String value) {
        // S2-016(http://struts.apache.org/development/2.x/docs/s2-016.html)
        for (String target : new String[] { name, value }) {
            if (target.matches(".*\\%\\{.+\\}.*")
                    || target.matches(".*\\$\\{.+\\}.*")) {
                return false;
            }
        }
        // S2-017(http://struts.apache.org/development/2.x/docs/s2-017.html)
        if (name.matches(".*redirect:.*")
                || name.matches(".*redirectAction:.*")) {
            return false;
        }

        return true;
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

web.xmlの設定

コンパイルして適当に配置し、web.xmlに以下の様に記述する事で、フィルタとして機能します。注意点として、サーブレットフィルタの実行順は、web.xml中に記載したfilter-mappingの順になるという点が挙げられます。

このため、struts2用のフィルタ設定よりも前に、以下の設定を記述する必要があります。

web.xml
  <filter>
    <filter-name>s2016filter</filter-name>
    <filter-class>com.example.s2016filter.AttackURLParamBlockFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>s2016filter</filter-name>
    <url-pattern>*</url-pattern>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>

効果を確認する

strutsのホームページに記載されている検証用のコードにより効果を確認する事が出来ます。

どのような場合に有効か

struts2のバージョンアップが出来ない場合も、Apacheのmod_rewriteやファイアウォールなどで防御すれば良いだけなので、あまり有効な場面は無いかも知れません。ApacheなどのWebサーバと連携していない場合も、UrlRewriteFilterを利用すれば同じ事が出来ます。

5
7
7

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
5
7