VYPR
High severityNVD Advisory· Published Oct 28, 2013· Updated Apr 29, 2026

CVE-2013-2186

CVE-2013-2186

Description

The DiskFileItem class in Apache Commons FileUpload, as used in Red Hat JBoss BRMS 5.3.1; JBoss Portal 4.3 CP07, 5.2.2, and 6.0.0; and Red Hat JBoss Web Server 1.0.2 allows remote attackers to write to arbitrary files via a NULL byte in a file name in a serialized instance.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
commons-fileupload:commons-fileuploadMaven
< 1.3.11.3.1

Affected products

7

Patches

1
163a6061fbc0

When deserializing DiskFileItems ensure that the repository location, if any, is a valid one.

https://github.com/apache/commons-fileuploadMark ThomasJul 25, 2013via ghsa
3 files changed · +126 38
  • src/changes/changes.xml+7 0 modified
    @@ -43,6 +43,13 @@ The <action> type attribute can be add,update,fix,remove.
       </properties>
     
       <body>
    +    <release version="1.3.1" description="maintenance release" date="TBD">
    +      <action dev="markt" type="fix" due-to="Arun Babu Neelicattu" due-to-email="abn@redhat.com">
    +        When deserializing DiskFileItems ensure that the repository location, if
    +        any, is a valid one.
    +      </action>
    +    </release>
    +    
         <release version="1.3" description="maintenance release, JDK1.5 update" date="2013-03-27">
           <!-- important notes -->
           <action dev="markt" type="fix">
    
  • src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java+20 0 modified
    @@ -656,6 +656,26 @@ private void readObject(ObjectInputStream in)
             // read values
             in.defaultReadObject();
     
    +        /* One expected use of serialization is to migrate HTTP sessions
    +         * containing a DiskFileItem between JVMs. Particularly if the JVMs are
    +         * on different machines It is possible that the repository location is
    +         * not valid so validate it.
    +         */
    +        if (repository != null) {
    +            if (repository.isDirectory()) {
    +                // Check path for nulls
    +                if (repository.getPath().contains("\0")) {
    +                    throw new IOException(format(
    +                            "The repository [%s] contains a null character",
    +                            repository.getPath()));
    +                }
    +            } else {
    +                throw new IOException(format(
    +                        "The repository [%s] is not a directory",
    +                        repository.getAbsolutePath()));
    +            }
    +        }
    +
             OutputStream output = getOutputStream();
             if (cachedContent != null) {
                 output.write(cachedContent);
    
  • src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java+99 38 modified
    @@ -24,6 +24,7 @@
     
     import java.io.ByteArrayInputStream;
     import java.io.ByteArrayOutputStream;
    +import java.io.File;
     import java.io.IOException;
     import java.io.ObjectInputStream;
     import java.io.ObjectOutputStream;
    @@ -51,14 +52,10 @@ public class DiskFileItemSerializeTest {
         private static final int threshold = 16;
     
         /**
    -     * Test creation of a field for which the amount of data falls below the
    -     * configured threshold.
    +     * Helper method to test creation of a field when a repository is used.
          */
    -    @Test
    -    public void testBelowThreshold() throws Exception {
    -        // Create the FileItem
    -        byte[] testFieldValueBytes = createContentBytes(threshold - 1);
    -        FileItem item = createFileItem(testFieldValueBytes);
    +    public void testInMemoryObject(byte[] testFieldValueBytes, File repository) {
    +        FileItem item = createFileItem(testFieldValueBytes, repository);
     
             // Check state is as expected
             assertTrue("Initial: in memory", item.isInMemory());
    @@ -75,6 +72,24 @@ public void testBelowThreshold() throws Exception {
             // Compare FileItem's (except byte[])
             compareFileItems(item, newItem);
         }
    +    
    +    /**
    +     * Helper method to test creation of a field.
    +     */
    +    private void testInMemoryObject(byte[] testFieldValueBytes) {
    +        testInMemoryObject(testFieldValueBytes, null);
    +    }
    +    
    +    /**
    +     * Test creation of a field for which the amount of data falls below the
    +     * configured threshold.
    +     */
    +    @Test
    +    public void testBelowThreshold() throws Exception {
    +        // Create the FileItem
    +        byte[] testFieldValueBytes = createContentBytes(threshold - 1);
    +        testInMemoryObject(testFieldValueBytes);
    +    }
     
         /**
          * Test creation of a field for which the amount of data equals the
    @@ -84,23 +99,7 @@ public void testBelowThreshold() throws Exception {
         public void testThreshold() throws Exception {
             // Create the FileItem
             byte[] testFieldValueBytes = createContentBytes(threshold);
    -        FileItem item = createFileItem(testFieldValueBytes);
    -
    -        // Check state is as expected
    -        assertTrue("Initial: in memory", item.isInMemory());
    -        assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    -        compareBytes("Initial", item.get(), testFieldValueBytes);
    -
    -
    -        // Serialize & Deserialize
    -        FileItem newItem = (FileItem)serializeDeserialize(item);
    -
    -        // Test deserialized content is as expected
    -        assertTrue("Check in memory", newItem.isInMemory());
    -        compareBytes("Check", testFieldValueBytes, newItem.get());
    -
    -        // Compare FileItem's (except byte[])
    -        compareFileItems(item, newItem);
    +        testInMemoryObject(testFieldValueBytes);
         }
     
         /**
    @@ -128,6 +127,41 @@ public void testAboveThreshold() throws Exception {
             // Compare FileItem's (except byte[])
             compareFileItems(item, newItem);
         }
    +    
    +    /**
    +     * Test serialization and deserialization when repository is not null.
    +     */
    +    @Test
    +    public void testValidRepository() throws Exception {
    +        // Create the FileItem
    +        byte[] testFieldValueBytes = createContentBytes(threshold);
    +        File repository = new File(System.getProperty("java.io.tmpdir"));
    +        testInMemoryObject(testFieldValueBytes, repository);
    +    }
    +    
    +    /**
    +     * Test deserialization fails when repository is not valid.
    +     */
    +    @Test(expected=IOException.class)
    +    public void testInvalidRepository() throws Exception {
    +        // Create the FileItem
    +        byte[] testFieldValueBytes = createContentBytes(threshold);
    +        File repository = new File(System.getProperty("java.io.tmpdir") + "file");
    +        FileItem item = createFileItem(testFieldValueBytes, repository);
    +        deserialize(serialize(item));
    +    }
    +    
    +    /**
    +     * Test deserialization fails when repository contains a null character.
    +     */
    +    @Test(expected=IOException.class)
    +    public void testInvalidRepositoryWithNullChar() throws Exception {
    +        // Create the FileItem
    +        byte[] testFieldValueBytes = createContentBytes(threshold);
    +        File repository = new File(System.getProperty("java.io.tmpdir") + "\0");
    +        FileItem item = createFileItem(testFieldValueBytes, repository);
    +        deserialize(serialize(item));
    +    }
     
         /**
          * Compare FileItem's (except the byte[] content)
    @@ -169,10 +203,10 @@ private byte[] createContentBytes(int size) {
         }
     
         /**
    -     * Create a FileItem with the specfied content bytes.
    +     * Create a FileItem with the specfied content bytes and repository.
          */
    -    private FileItem createFileItem(byte[] contentBytes) {
    -        FileItemFactory factory = new DiskFileItemFactory(threshold, null);
    +    private FileItem createFileItem(byte[] contentBytes, File repository) {
    +        FileItemFactory factory = new DiskFileItemFactory(threshold, repository);
             String textFieldName = "textField";
     
             FileItem item = factory.createItem(
    @@ -192,33 +226,60 @@ private FileItem createFileItem(byte[] contentBytes) {
             return item;
     
         }
    +    
    +    /**
    +     * Create a FileItem with the specfied content bytes.
    +     */
    +    private FileItem createFileItem(byte[] contentBytes) {
    +        return createFileItem(contentBytes, null);
    +    }
    +    
    +    /**
    +     * Do serialization
    +     */
    +    private ByteArrayOutputStream serialize(Object target) throws Exception {
    +        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    +        ObjectOutputStream oos = new ObjectOutputStream(baos);
    +        oos.writeObject(target);
    +        oos.flush();
    +        oos.close();
    +        return baos;
    +    }
    +    
    +    /**
    +     * Do deserialization
    +     */
    +    private Object deserialize(ByteArrayOutputStream baos) throws Exception {
    +        Object result = null;
    +        ByteArrayInputStream bais =
    +                new ByteArrayInputStream(baos.toByteArray());
    +        ObjectInputStream ois = new ObjectInputStream(bais);
    +        result = ois.readObject();
    +        bais.close();
     
    +        return result;
    +    }
    +    
         /**
          * Do serialization and deserialization.
          */
         private Object serializeDeserialize(Object target) {
             // Serialize the test object
    -        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    +        ByteArrayOutputStream baos = null;
             try {
    -            ObjectOutputStream oos = new ObjectOutputStream(baos);
    -            oos.writeObject(target);
    -            oos.flush();
    -            oos.close();
    +            baos = serialize(target);
             } catch (Exception e) {
                 fail("Exception during serialization: " + e);
             }
    -
    +        
             // Deserialize the test object
             Object result = null;
             try {
    -            ByteArrayInputStream bais =
    -                new ByteArrayInputStream(baos.toByteArray());
    -            ObjectInputStream ois = new ObjectInputStream(bais);
    -            result = ois.readObject();
    -            bais.close();
    +            result = deserialize(baos);
             } catch (Exception e) {
                 fail("Exception during deserialization: " + e);
             }
    +        
             return result;
         }
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

23

News mentions

0

No linked articles in our index yet.