CVE-2014-3490 (published 2014-08-19T18:55Z)

RESTEasy 2.3.1 before 2.3.8.SP2 and 3.x before 3.0.9, as used in Red Hat JBoss Enterprise Application Platform (EAP) 6.3.0, does not disable external entities when the resteasy.document.expand.entity.references parameter is set to false, which allows remote attackers to read arbitrary files and have other unspecified impact via unspecified vectors, related to an XML External Entity (XXE) issue.  NOTE: this vulnerability exists because of an incomplete fix for CVE-2012-0818.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)

Weakness information:
cwe_id: NVD-CWE-Other
cwe_name: Other
description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/ronsigal/Resteasy
commit_details: repo_url: https://github.com/ronsigal/Resteasy
author: rsigal
author_date: 2014-07-19 21:29:55-04:00
msg: RESTEASY-1073: Prevent expansion of XML external parameter entities.
repository: repo_url: https://github.com/ronsigal/Resteasy
repo_name: ronsigal/Resteasy
description: REST and JAXRS
repo_language: Java
owner: ronsigal
file_changes: filename: pom.xml
change_type: ModificationType.ADD
diff: @@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.jboss.resteasy</groupId>
+    <artifactId>resteasy-jaxrs-all</artifactId>
+    <version>3.0.8.Final</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+
+  <artifactId>RESTEASY-1073-WF8</artifactId>
+  <packaging>jar</packaging>
+  <name>RESTEASY-1073-WF8</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <as-version>8.0.0.Final</as-version>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.12</version>
+      </plugin>
+        <plugin>
+            <artifactId>maven-dependency-plugin</artifactId>
+            <executions>
+                <execution>
+                    <id>unpack</id>
+                    <phase>process-test-classes</phase>
+                    <goals>
+                        <goal>unpack</goal>
+                    </goals>
+                    <configuration>
+                        <artifactItems>
+                            <artifactItem>
+                                <groupId>org.wildfly</groupId>
+                                <artifactId>wildfly-dist</artifactId>
+                                <version>${as-version}</version>
+                                <type>zip</type>
+                                <overWrite>false</overWrite>
+                                <outputDirectory>target</outputDirectory>
+                            </artifactItem>
+                        </artifactItems>
+                    </configuration>
+                </execution>
+            </executions>
+        </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <version>1.6</version>
+        <executions>
+          <execution>
+            <id>unpack resteasy</id>
+            <phase>process-test-classes</phase>
+            <configuration>
+              <target>
+                <unzip src="../../jboss-modules/target/resteasy-jboss-modules-wf8-${project.version}.zip"
+                       dest="${project.build.directory}/wildfly-${as-version}/modules/system/layers/base"
+                       overwrite="true" />
+              </target>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      
+     <plugin>
+       <groupId>org.apache.maven.plugins</groupId>
+       <artifactId>maven-war-plugin</artifactId>
+       <configuration>
+          <archive>
+             <manifestEntries>
+                <Dependencies>
+                javax.xml.bind.api
+                </Dependencies>
+             </manifestEntries>
+          </archive>
+       </configuration>
+     </plugin>
+     
+    </plugins>
+  </build>
+  
+<dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>org.jboss.arquillian</groupId>
+            <artifactId>arquillian-bom</artifactId>
+            <version>1.0.3.Final</version>
+            <scope>import</scope>
+            <type>pom</type>
+        </dependency>
+    </dependencies>
+</dependencyManagement>
+  
+  <dependencies>
+    <dependency>
+        <groupId>org.jboss.spec</groupId>
+        <artifactId>jboss-javaee-6.0</artifactId>
+        <version>1.0.0.Final</version>
+        <type>pom</type>
+        <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.arquillian.junit</groupId>
+        <artifactId>arquillian-junit-container</artifactId>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.wildfly</groupId>
+        <artifactId>wildfly-arquillian-container-managed</artifactId>
+        <version>8.0.0.Alpha1</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.arquillian.protocol</groupId>
+        <artifactId>arquillian-protocol-servlet</artifactId>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.resteasy</groupId>
+        <artifactId>jaxrs-api</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.resteasy</groupId>
+        <artifactId>resteasy-jaxrs</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.resteasy</groupId>
+        <artifactId>resteasy-validator-provider-11</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+    <dependency>
+        <groupId>javax.validation</groupId>
+        <artifactId>validation-api</artifactId>
+        <version>1.1.0.Final</version>
+    </dependency>
+    <dependency>
+        <groupId>org.hibernate</groupId> 
+        <artifactId>hibernate-validator</artifactId>
+        <version>5.0.1.Final</version>
+    </dependency>
+    <dependency>
+        <groupId>javax.el</groupId>
+        <artifactId>javax.el-api</artifactId>
+        <version>2.2.4</version>
+    </dependency>
+    <dependency>
+        <groupId>org.glassfish.web</groupId>
+        <artifactId>javax.el</artifactId>
+        <version>2.2.4</version>
+    </dependency>
+<dependency>
+  <groupId>org.jboss.spec.javax.xml.bind</groupId>
+  <artifactId>jboss-jaxb-api_2.2_spec</artifactId>
+  <version>1.0.4.Final</version>
+</dependency>
+    <dependency>
+        <groupId>org.jboss.resteasy</groupId>
+        <artifactId>resteasy-jaxb-provider</artifactId>
+        <version>${project.version}</version>
+        <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

programming_language: HTML
filename: TestApplication.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,17 @@
+package org.jboss.resteasy.resteasy1073;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+
+public class TestApplication extends Application
+{
+   @Override
+   public Set<Class<?>> getClasses() {
+      HashSet<Class<?>> set = new HashSet<Class<?>>();
+      set.add(TestResource.class);
+      return set;
+   }
+}
+

programming_language: Java
filename: TestResource.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,26 @@
+package org.jboss.resteasy.resteasy1073;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * RESTEASY-1073
+ * 
+ * @author <a href="ron.sigal@jboss.com">Ron Sigal</a>
+ * @version $Revision: 1.1 $
+ *
+ * Copyright July 19, 2014
+ */
+@Path("")
+public class TestResource
+{
+   @POST
+   @Path("test")
+   @Consumes(MediaType.APPLICATION_XML)
+   public String post(TestWrapper wrapper)
+   {
+      return wrapper.getName();
+   }
+}

programming_language: Java
filename: TestWrapper.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,17 @@
+package org.jboss.resteasy.resteasy1073;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class TestWrapper
+{
+   private String name;
+   public String getName()
+   {
+      return name;
+   }
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+}
\ No newline at end of file

programming_language: Java
filename: TestExternalParameterEntity.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,95 @@
+package org.jboss.resteasy.test.resteasy1073;
+
+import java.io.File;
+
+import javax.ws.rs.core.MediaType;
+
+import junit.framework.Assert;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.resteasy.client.ClientRequest;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.resteasy1073.TestApplication;
+import org.jboss.resteasy.resteasy1073.TestResource;
+import org.jboss.resteasy.resteasy1073.TestWrapper;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * RESTEASY-1073.
+ * 
+ * @author <a href="ron.sigal@jboss.com">Ron Sigal</a>
+ * @version $Revision: 1.1 $
+ *
+ * Created July 19, 2014
+ */
+@RunWith(Arquillian.class)
+public class TestExternalParameterEntity
+{  
+   @Deployment(name="war_expand", order=1)
+   public static Archive<?> createTestArchive1()
+   {
+      WebArchive war = ShrinkWrap.create(WebArchive.class, "RESTEASY-1073-expand.war")
+            .addClasses(TestApplication.class)
+            .addClasses(TestResource.class, TestWrapper.class)
+            .addAsWebInfResource("web_expand.xml", "web.xml")
+            ;
+      System.out.println(war.toString(true));
+      return war;
+   }
+
+   @Deployment(name="war_no_expand", order=2)
+   public static Archive<?> createTestArchive2()
+   {
+      WebArchive war = ShrinkWrap.create(WebArchive.class, "RESTEASY-1073-no-expand.war")
+            .addClasses(TestApplication.class)
+            .addClasses(TestResource.class, TestWrapper.class)
+            .addAsWebInfResource("web_no_expand.xml", "web.xml")
+            ;
+      System.out.println(war.toString(true));
+      return war;
+   }
+   
+   private String passwdFile = new File("src/test/resources/passwd").getAbsolutePath();
+   private String dtdFile = new File("src/test/resources/test.dtd").getAbsolutePath();
+      
+   private String text =
+"<!DOCTYPE foo [\r" +
+"  <!ENTITY % file SYSTEM \"" + passwdFile + "\">\r" +
+"  <!ENTITY % start \"<![CDATA[\">\r" + 
+"  <!ENTITY % end \"]]>\">\r" +
+"  <!ENTITY % dtd SYSTEM \"" + dtdFile + "\">\r" +
+"%dtd;\r" +
+"]>\r" +
+"<testWrapper><name>&xxe;</name></testWrapper>";
+   
+   @Test
+   public void testExternalParameterEntityExpand() throws Exception
+   {
+      ClientRequest request = new ClientRequest("http://localhost:8080/RESTEASY-1073-expand/test");
+      System.out.println(text);
+      request.body(MediaType.APPLICATION_XML, text);
+      ClientResponse<?> response = request.post();
+      Assert.assertEquals(200, response.getStatus());
+      String entity = response.getEntity(String.class);
+      System.out.println("Result: " + entity);
+      Assert.assertEquals("root:x:0:0:root:/root:/bin/bash", entity.trim());
+   }
+   
+   @Test
+   public void testExternalParameterEntityNoExpand() throws Exception
+   {
+      ClientRequest request = new ClientRequest("http://localhost:8080/RESTEASY-1073-no-expand/test");
+      System.out.println(text);
+      request.body(MediaType.APPLICATION_XML, text);
+      ClientResponse<?> response = request.post();
+      Assert.assertEquals(200, response.getStatus());
+      String entity = response.getEntity(String.class);
+      System.out.println("Result: " + entity);
+      Assert.assertEquals("", entity.trim());
+   }
+}

programming_language: Java
filename: arquillian.xml
change_type: ModificationType.ADD
diff: @@ -0,0 +1,23 @@
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="
+        http://jboss.org/schema/arquillian
+        http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+    
+   <!-- Force the use of the Servlet 3.0 protocol with all containers, as it is the most mature -->
+   <defaultProtocol type="Servlet 3.0" />
+   
+    <engine>
+        <property name="deploymentExportPath">target/deployments</property>
+    </engine>
+   
+   <container qualifier="jbossas-managed" default="true">
+     <configuration>
+       <property name="jbossHome">target/wildfly-8.0.0.Final</property>
+       <!--property name="javaHome">/opt/local/java/jdk1.7.0_21</property-->
+       <property name="serverConfig">standalone-full.xml</property>
+       <!-- Uncomment next line to run server in debug mode.  -->
+       <!--property name="javaVmArguments">-Xmx512m -XX:MaxPermSize=128m -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</property-->
+     </configuration>
+   </container>
+</arquillian>
\ No newline at end of file

programming_language: CoffeeScript
filename: passwd
change_type: ModificationType.ADD
diff: @@ -0,0 +1 @@
+root:x:0:0:root:/root:/bin/bash
\ No newline at end of file

programming_language: Shell
filename: test.dtd
change_type: ModificationType.ADD
diff: @@ -0,0 +1 @@
+<!ENTITY xxe "%start; %file; %end;">

programming_language: Batchfile
filename: web_expand.xml
change_type: ModificationType.ADD
diff: @@ -0,0 +1,29 @@
+<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+
+    <display-name>RESTEASY-1073-Expand</display-name>
+
+    <context-param>
+       <param-name>resteasy.document.expand.entity.references</param-name>
+       <param-value>true</param-value>
+    </context-param>
+    
+    <servlet>
+        <servlet-name>Resteasy</servlet-name>
+
+        <servlet-class>
+            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
+        </servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.jboss.resteasy.resteasy1073.TestApplication</param-value>
+        </init-param>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>Resteasy</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
\ No newline at end of file

programming_language: PowerShell
filename: web_no_expand.xml
change_type: ModificationType.ADD
diff: @@ -0,0 +1,29 @@
+<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+
+    <display-name>RESTEASY-1073-NoExpand</display-name>
+
+    <context-param>
+       <param-name>resteasy.document.expand.entity.references</param-name>
+       <param-value>false</param-value>
+    </context-param>
+     
+    <servlet>
+        <servlet-name>Resteasy</servlet-name>
+
+        <servlet-class>
+            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
+        </servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.jboss.resteasy.resteasy1073.TestApplication</param-value>
+        </init-param>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>Resteasy</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
\ No newline at end of file

programming_language: PowerShell
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -30,6 +30,7 @@
         <module>RESTEASY-1056-jetty-bv11</module>
         <module>RESTEASY-1056-jetty-bv10</module>
         <module>RESTEASY-1058-WF8</module>
+        <module>RESTEASY-1073-WF8</module>
     </modules>
     
     <artifactId>arquillian</artifactId>

programming_language: SQL
filename: ExternalEntityUnmarshaller.java
change_type: ModificationType.MODIFY
diff: @@ -154,6 +154,7 @@ public class ExternalEntityUnmarshaller implements Unmarshaller {
           XMLReader xmlReader = sp.getXMLReader();
           xmlReader.setFeature("http://xml.org/sax/features/validation", false);
           xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+          xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
           xmlReader.setFeature("http://xml.org/sax/features/namespaces", true);
           SAXSource saxSource = new SAXSource(xmlReader, source);
           return delegate.unmarshal(saxSource);
@@ -199,6 +200,7 @@ public class ExternalEntityUnmarshaller implements Unmarshaller {
             XMLReader xmlReader = sp.getXMLReader();
             xmlReader.setFeature("http://xml.org/sax/features/validation", false);
             xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
             xmlReader.setFeature("http://xml.org/sax/features/namespaces", true);
             ((SAXSource) source).setXMLReader(xmlReader);
             return delegate.unmarshal(source, declaredType);

programming_language: Java