gil pushed to struts (master). "fix CVE-2015-0899 (rhbz#1207099)"

notifications at fedoraproject.org notifications at fedoraproject.org
Mon Mar 30 10:50:59 UTC 2015


>From 5f83bd9f5d94ea6dd621748a5c637eef2699eb33 Mon Sep 17 00:00:00 2001
From: gil <puntogil at libero.it>
Date: Mon, 30 Mar 2015 12:50:36 +0200
Subject: fix CVE-2015-0899 (rhbz#1207099)


diff --git a/struts-1.3.10-CVE-2015-0899.patch b/struts-1.3.10-CVE-2015-0899.patch
new file mode 100644
index 0000000..a4129cf
--- /dev/null
+++ b/struts-1.3.10-CVE-2015-0899.patch
@@ -0,0 +1,441 @@
+diff -Nru struts-1.3.10/src/core/pom.xml struts-1.3.10.CVE-2015-0899/src/core/pom.xml
+--- struts-1.3.10/src/core/pom.xml	2015-03-30 12:13:30.943199760 +0200
++++ struts-1.3.10.CVE-2015-0899/src/core/pom.xml	2015-03-30 12:40:00.302267718 +0200
+@@ -184,6 +184,12 @@
+             <artifactId>oro</artifactId>
+             <version>2.0.8</version>
+         </dependency>
++        <dependency>
++            <groupId>log4j</groupId>
++            <artifactId>log4j</artifactId>
++            <version>1.2.17</version>
++            <scope>test</scope>
++        </dependency>
+     </dependencies>
+ 
+ </project>
+diff -Nru struts-1.3.10/src/core/src/main/java/org/apache/struts/config/ActionConfig.java struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/config/ActionConfig.java
+--- struts-1.3.10/src/core/src/main/java/org/apache/struts/config/ActionConfig.java	2008-06-05 00:13:42.000000000 +0200
++++ struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/config/ActionConfig.java	2015-03-30 12:20:14.202124216 +0200
+@@ -861,6 +861,36 @@
+         }
+     }
+ 
++    // 2014/07/02 - security problem patch.
++    // Author: NTT DATA Corporation
++    /**
++     * Accepted page value for multi-page validation.<br>
++     * If two or more page values are accepted, then acceptPage is set minimum of them.<br>
++     * If multi-page validation is not use, acceptPage is not set. Then multi-page validation is disabled.
++     * @since Struts 1.2.9-sp2
++     */
++    protected Integer acceptPage = null;
++
++    /**
++     * Returns accepted page value for multi-page validation.
++     *
++     * @return Accepted page value for multi-page validation
++     * @since  Struts 1.2.9-sp2
++     */
++    public Integer getAcceptPage() {
++        return acceptPage;
++    }
++
++    /**
++     * Set accepted page value for multi-page validation.
++     *
++     * @param acceptPage Accepted page value for multi-page validation
++     * @since  Struts 1.2.9-sp2
++     */
++    public void setAcceptPage(Integer acceptPage) {
++        this.acceptPage = acceptPage;
++    }
++    
+     // --------------------------------------------------------- Public Methods
+ 
+     /**
+@@ -1283,6 +1313,11 @@
+             sb.append(type);
+         }
+ 
++        // 2014/07/02 - security problem patch.
++        // Author: NTT DATA Corporation
++        sb.append(",acceptPage=");
++        sb.append(acceptPage);
++
+         return (sb.toString());
+     }
+ }
+diff -Nru struts-1.3.10/src/core/src/main/java/org/apache/struts/util/RequestUtils.java struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/util/RequestUtils.java
+--- struts-1.3.10/src/core/src/main/java/org/apache/struts/util/RequestUtils.java	2015-03-30 12:13:31.002196823 +0200
++++ struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/util/RequestUtils.java	2015-03-30 12:23:40.352806356 +0200
+@@ -469,6 +469,14 @@
+                 parameterValue = request.getParameterValues(name);
+             }
+ 
++            // 2014/05/13 - CVE-2014-0114 security problem patch.
++            // Author: NTT DATA Corporation
++            if (stripped.startsWith("class.") || stripped.indexOf(".class.") >= 0) {
++                // this log output is only for detection of invalid parameters and not an integral part of the bug fix
++                log.info("ignore parameter: paramName=" + stripped);
++                continue;
++            }
++
+             // Populate parameters, except "standard" struts attributes
+             // such as 'org.apache.struts.action.CANCEL'
+             if (!(stripped.startsWith("org.apache.struts."))
+diff -Nru struts-1.3.10/src/core/src/main/java/org/apache/struts/validator/DynaValidatorForm.java struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/validator/DynaValidatorForm.java
+--- struts-1.3.10/src/core/src/main/java/org/apache/struts/validator/DynaValidatorForm.java	2008-06-05 00:14:02.000000000 +0200
++++ struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/validator/DynaValidatorForm.java	2015-03-30 12:22:30.733325776 +0200
+@@ -112,9 +112,12 @@
+ 
+         String validationKey = getValidationKey(mapping, request);
+ 
++        // 2014/07/02 - security problem patch.
++        // Author: NTT DATA Corporation
++        int validationPage = determinePage(mapping, request);
+         Validator validator =
+             Resources.initValidator(validationKey, this, application, request,
+-                errors, page);
++                errors, validationPage);
+ 
+         try {
+             validatorResults = validator.validate();
+@@ -125,6 +128,24 @@
+         return errors;
+     }
+ 
++    // 2014/07/02 - security problem patch.
++    // Author: NTT DATA Corporation
++    /**
++     * Determine validation page.<br>
++     * If acceptPage of ActionMapping is null, then returns Integer.MAX_VALUE.
++     * (multi-page validation is disabled. All validation fields are enabled.)<br>
++     * If page property is less than acceptPage of ActionMapping, returns acceptPage value.<br>
++     * If page property is greater than or equal to acceptPage of ActionMapping, returns page property value.
++     * @param mapping The mapping used to select this instance.
++     * @param request The servlet request we are processing.
++     * @return validation page.
++     * @since Struts 1.2.9-sp2
++     */
++    protected int determinePage(ActionMapping mapping, HttpServletRequest request) {
++        Integer acceptPage = mapping.getAcceptPage();
++        return acceptPage != null ? Math.max(acceptPage.intValue(), page) : Integer.MAX_VALUE;
++    }
++
+     /**
+      * Returns the Validation key.
+      *
+diff -Nru struts-1.3.10/src/core/src/main/java/org/apache/struts/validator/ValidatorForm.java struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/validator/ValidatorForm.java
+--- struts-1.3.10/src/core/src/main/java/org/apache/struts/validator/ValidatorForm.java	2008-06-05 00:14:02.000000000 +0200
++++ struts-1.3.10.CVE-2015-0899/src/core/src/main/java/org/apache/struts/validator/ValidatorForm.java	2015-03-30 12:36:22.312287599 +0200
+@@ -108,9 +108,12 @@
+ 
+         String validationKey = getValidationKey(mapping, request);
+ 
++        // 2014/07/02 - security problem patch.
++        // Author: NTT DATA Corporation
++        int validationPage = determinePage(mapping, request);
+         Validator validator =
+             Resources.initValidator(validationKey, this, application, request,
+-                errors, page);
++                errors, validationPage);
+ 
+         try {
+             validatorResults = validator.validate();
+@@ -121,6 +124,24 @@
+         return errors;
+     }
+ 
++    // 2014/07/02 - security problem patch.
++    // Author: NTT DATA Corporation
++    /**
++     * Determine validation page.<br>
++     * If acceptPage of ActionMapping is null, then returns Integer.MAX_VALUE.
++     * (multi-page validation is disabled. All validation fields are enabled.)<br>
++     * If page property is less than acceptPage of ActionMapping, returns acceptPage value.<br>
++     * If page property is greater than or equal to acceptPage of ActionMapping, returns page property value.
++     * @param mapping The mapping used to select this instance.
++     * @param request The servlet request we are processing.
++     * @return validation page.
++     * @since Struts 1.2.9-sp2
++     */
++    protected int determinePage(ActionMapping mapping, HttpServletRequest request) {
++        Integer acceptPage = mapping.getAcceptPage();
++        return acceptPage != null ? Math.max(acceptPage.intValue(), page) : Integer.MAX_VALUE;
++    }
++
+     /**
+      * Returns the Validation key.
+      *
+diff -Nru struts-1.3.10/src/core/src/test/java/org/apache/struts/util/TestRequestUtilsPopulate.java struts-1.3.10.CVE-2015-0899/src/core/src/test/java/org/apache/struts/util/TestRequestUtilsPopulate.java
+--- struts-1.3.10/src/core/src/test/java/org/apache/struts/util/TestRequestUtilsPopulate.java	2015-03-30 12:13:30.984197719 +0200
++++ struts-1.3.10.CVE-2015-0899/src/core/src/test/java/org/apache/struts/util/TestRequestUtilsPopulate.java	2015-03-30 12:33:30.592968395 +0200
+@@ -21,11 +21,19 @@
+ 
+ package org.apache.struts.util;
+ 
++import java.io.BufferedReader;
++import java.io.StringReader;
++import java.io.StringWriter;
++import java.util.HashSet;
++
+ import javax.servlet.ServletException;
+ 
+ import junit.framework.Test;
+ import junit.framework.TestSuite;
+ 
++import org.apache.log4j.LogManager;
++import org.apache.log4j.PatternLayout;
++import org.apache.log4j.WriterAppender;
+ import org.apache.struts.action.ActionMapping;
+ import org.apache.struts.util.RequestUtils;
+ import org.apache.struts.Globals;
+@@ -120,4 +128,247 @@
+ 
+     }
+ 
++    /** 
++     * Ensure that the parameter of HTTP request
++     * which causes ClassLoader manipulation is ignored.
++     *
++     * The purpose of this test is to ensure that security problem
++     * CVE-2014-0114 is fixed.
++     *
++     */
++    public void testRequestParameterIgnore1() throws Exception {
++
++        String stringValue     = "Test";
++
++        MockFormBean  mockForm = new MockFormBean();
++
++        // Set up the mock HttpServletRequest
++        request.setMethod("GET");
++        request.setContentType("");
++
++        request.addParameter("class.xxx.case1", stringValue);
++
++        // logger
++        StringWriter writer = new StringWriter();
++        WriterAppender appender = new WriterAppender(new PatternLayout("%p, %m%n"), writer);
++        LogManager.getRootLogger().addAppender(appender);
++        LogManager.getRootLogger().setAdditivity(false);
++
++        // Try to populate
++        HashSet ignoreSet = new HashSet();
++        try {
++            RequestUtils.populate(mockForm, request);
++
++            String keyword1 = "INFO, ";
++            String keyword2 = "ignore parameter: paramName=";
++            String logString = writer.toString();
++            StringReader reader = new StringReader(logString);
++            BufferedReader bufReader = new BufferedReader(reader);
++            String line = null;
++            while ((line = bufReader.readLine()) != null) {
++                if (!line.startsWith(keyword1)) {
++                	continue;
++                }
++                int pos = line.indexOf(keyword2);
++                if (pos >= 0) {
++                    ignoreSet.add(line.substring(pos + keyword2.length()));
++                }
++            }
++        } catch(ServletException se) {
++        	fail("Occur exception.");
++        } finally {
++            LogManager.getRootLogger().removeAppender(appender);
++            LogManager.getRootLogger().setAdditivity(true);
++        }
++
++        // Check 
++        assertEquals("ignore num no match", 1, ignoreSet.size());
++        assertTrue("not exists ignore parameter class.xxx.case1", ignoreSet.contains("class.xxx.case1"));
++        assertNull("ActionForm property set", mockForm.getStringProperty());
++
++    }
++
++    /** 
++     * Ensure that the parameter of HTTP request
++     * which causes ClassLoader manipulation is ignored.
++     *
++     * The purpose of this test is to ensure that security problem
++     * CVE-2014-0114 is fixed.
++     *
++     */
++    public void testRequestParameterIgnore2() throws Exception {
++
++        String stringValue     = "Test";
++
++        MockFormBean  mockForm = new MockFormBean();
++
++        // Set up the mock HttpServletRequest
++        request.setMethod("GET");
++        request.setContentType("");
++
++        request.addParameter("xxx.class.case2", stringValue);
++
++        // logger
++        StringWriter writer = new StringWriter();
++        WriterAppender appender = new WriterAppender(new PatternLayout("%p, %m%n"), writer);
++        LogManager.getRootLogger().addAppender(appender);
++        LogManager.getRootLogger().setAdditivity(false);
++
++        // Try to populate
++        HashSet ignoreSet = new HashSet();
++        try {
++            RequestUtils.populate(mockForm, request);
++
++            String keyword1 = "INFO, ";
++            String keyword2 = "ignore parameter: paramName=";
++            String logString = writer.toString();
++            StringReader reader = new StringReader(logString);
++            BufferedReader bufReader = new BufferedReader(reader);
++            String line = null;
++            while ((line = bufReader.readLine()) != null) {
++                if (!line.startsWith(keyword1)) {
++                	continue;
++                }
++                int pos = line.indexOf(keyword2);
++                if (pos >= 0) {
++                    ignoreSet.add(line.substring(pos + keyword2.length()));
++                }
++            }
++        } catch(ServletException se) {
++        	fail("Occur exception.");
++        } finally {
++            LogManager.getRootLogger().removeAppender(appender);
++            LogManager.getRootLogger().setAdditivity(true);
++        }
++
++        // Check 
++        assertEquals("ignore num no match", 1, ignoreSet.size());
++        assertTrue("not exists ignore parameter xxx.class.case2", ignoreSet.contains("xxx.class.case2"));
++        assertNull("ActionForm property set", mockForm.getStringProperty());
++
++    }
++
++    /** 
++     * Ensure that the parameter of HTTP request
++     * which causes ClassLoader manipulation is ignored.
++     *
++     * The purpose of this test is to ensure that security problem
++     * CVE-2014-0114 is fixed.
++     *
++     */
++    public void testRequestParameterIgnore3() throws Exception {
++
++        String stringValue     = "Test";
++
++        MockFormBean  mockForm = new MockFormBean();
++
++        // Set up the mock HttpServletRequest
++        request.setMethod("GET");
++        request.setContentType("");
++
++        request.addParameter("stringProperty", stringValue);
++
++        // logger
++        StringWriter writer = new StringWriter();
++        WriterAppender appender = new WriterAppender(new PatternLayout("%p, %m%n"), writer);
++        LogManager.getRootLogger().addAppender(appender);
++        LogManager.getRootLogger().setAdditivity(false);
++
++        // Try to populate
++        HashSet ignoreSet = new HashSet();
++        try {
++            RequestUtils.populate(mockForm, request);
++
++            String keyword1 = "INFO, ";
++            String keyword2 = "ignore parameter: paramName=";
++            String logString = writer.toString();
++            StringReader reader = new StringReader(logString);
++            BufferedReader bufReader = new BufferedReader(reader);
++            String line = null;
++            while ((line = bufReader.readLine()) != null) {
++                if (!line.startsWith(keyword1)) {
++                	continue;
++                }
++                int pos = line.indexOf(keyword2);
++                if (pos >= 0) {
++                    ignoreSet.add(line.substring(pos + keyword2.length()));
++                }
++            }
++        } catch(ServletException se) {
++        	fail("Occur exception.");
++        } finally {
++            LogManager.getRootLogger().removeAppender(appender);
++            LogManager.getRootLogger().setAdditivity(true);
++        }
++
++        // Check 
++        assertEquals("ignore num no match", 0, ignoreSet.size());
++        assertFalse("exists ignore parameter stringProperty", ignoreSet.contains("stringProperty"));
++        assertEquals("ActionForm property not equal", stringValue, mockForm.getStringProperty());
++
++    }
++
++    /** 
++     * Ensure that the parameter of HTTP request
++     * which causes ClassLoader manipulation is ignored.
++     *
++     * The purpose of this test is to ensure that security problem
++     * CVE-2014-0114 is fixed.
++     *
++     */
++    public void testRequestParameterIgnore4() throws Exception {
++
++        String stringValue     = "Test";
++
++        MockFormBean  mockForm = new MockFormBean();
++
++        // Set up the mock HttpServletRequest
++        request.setMethod("GET");
++        request.setContentType("");
++
++        request.addParameter("class.xxx.case4", stringValue);
++        request.addParameter("xxx.class.case4", stringValue);
++        request.addParameter("stringProperty", stringValue);
++
++        // logger
++        StringWriter writer = new StringWriter();
++        WriterAppender appender = new WriterAppender(new PatternLayout("%p, %m%n"), writer);
++        LogManager.getRootLogger().addAppender(appender);
++        LogManager.getRootLogger().setAdditivity(false);
++
++        // Try to populate
++        HashSet ignoreSet = new HashSet();
++        try {
++            RequestUtils.populate(mockForm, request);
++
++            String keyword1 = "INFO, ";
++            String keyword2 = "ignore parameter: paramName=";
++            String logString = writer.toString();
++            StringReader reader = new StringReader(logString);
++            BufferedReader bufReader = new BufferedReader(reader);
++            String line = null;
++            while ((line = bufReader.readLine()) != null) {
++                if (!line.startsWith(keyword1)) {
++                	continue;
++                }
++                int pos = line.indexOf(keyword2);
++                if (pos >= 0) {
++                    ignoreSet.add(line.substring(pos + keyword2.length()));
++                }
++            }
++        } catch(ServletException se) {
++        	fail("Occur exception.");
++        } finally {
++            LogManager.getRootLogger().removeAppender(appender);
++            LogManager.getRootLogger().setAdditivity(true);
++        }
++
++        // Check 
++        assertEquals("ignore num no match", 2, ignoreSet.size());
++        assertTrue("not exists ignore parameter class.xxx.case4", ignoreSet.contains("class.xxx.case4"));
++        assertTrue("not exists ignore parameter xxx.class.case4", ignoreSet.contains("xxx.class.case4"));
++        assertEquals("ActionForm property not equal", stringValue, mockForm.getStringProperty());
++
++    }
++
+ }
diff --git a/struts.spec b/struts.spec
index 8f223e5..55b45c6 100644
--- a/struts.spec
+++ b/struts.spec
@@ -1,7 +1,7 @@
 %global master_version 4
 Name:          struts
 Version:       1.3.10
-Release:       13%{?dist}
+Release:       14%{?dist}
 Summary:       Web application framework
 License:       ASL 2.0
 URL:           http://struts.apache.org/
@@ -32,6 +32,8 @@ Patch1:        %{name}-%{version}-jboss.patch
 # and Brandon.Vincent at asu.edu
 Patch2:        struts-1.3.10-CVE-2014-0114.patch
 
+Patch3:        struts-1.3.10-CVE-2015-0899.patch
+
 BuildRequires: mvn(antlr:antlr)
 BuildRequires: mvn(commons-beanutils:commons-beanutils)
 BuildRequires: mvn(commons-chain:commons-chain)
@@ -40,6 +42,11 @@ BuildRequires: mvn(commons-fileupload:commons-fileupload)
 BuildRequires: mvn(commons-logging:commons-logging)
 BuildRequires: mvn(commons-validator:commons-validator)
 BuildRequires: mvn(junit:junit)
+%if %{?fedora} >= 21
+BuildRequires: mvn(log4j:log4j:1.2.17)
+%else
+BuildRequires: mvn(log4j:log4j)
+%endif
 BuildRequires: mvn(org.apache.bsf:bsf)
 BuildRequires: mvn(org.jboss.spec.javax.el:jboss-el-api_2.2_spec)
 BuildRequires: mvn(org.jboss.spec.javax.faces:jboss-jsf-api_2.1_spec)
@@ -84,6 +91,7 @@ find -name "*.class" -delete
 %patch0 -p0
 %patch1 -p1
 %patch2 -p0
+%patch3 -p1
 
 sed -i 's/\r//' LICENSE.txt NOTICE.txt
 
@@ -125,6 +133,9 @@ cd src
 %license LICENSE.txt NOTICE.txt
 
 %changelog
+* Mon Mar 30 2015 gil cattaneo <puntogil at libero.it> 1.3.10-14
+- fix CVE-2015-0899 (rhbz#1207099)
+
 * Thu Feb 12 2015 gil cattaneo <puntogil at libero.it> 1.3.10-13
 - introduce license macro
 
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/struts.git/commit/?h=master&id=5f83bd9f5d94ea6dd621748a5c637eef2699eb33


More information about the scm-commits mailing list