Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8011539

File APIs Should Not Allow Null Bytes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 7
    • core-libs
    • None

      A DESCRIPTION OF THE REQUEST :
      When creating a file, if you pass a String including a null byte, the underlying OS will create the file with the name truncated at the null byte.

      This is true not just for Win7/32bit, but also for any other operating system.



      JUSTIFICATION :
      This creates a serious security issue. Naive code may try to validate filenames by checking that the extension is " safe " - allowing filenames that end in .txt and disallowing filenames that end in .exe. That validation code will see " Hello.exe%00.txt " as legal, even though the file created will be " Hello.exe " .

      In the case of file uploads, an attacker can upload executable files using this weakness.

      FYI - .NET does not allow a string containing a null byte to be used by the file APIs.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      When a file API receives a string to be used as a filename, it should throw an exception if the string contains characters that are illegal in the underlying filesystem's naming rules.
      ACTUAL -
      Passing " Hello.exe%00.txt " to the constructor for java.io.FileOutputStream will create the file " Hello.exe " on the filesystem.

      ---------- BEGIN SOURCE ----------
      public static void main(String[] args) {

      char[] foo = {'C', ':', '\\', 'f', '\\', 'H', 'e', 'l', 'l', 'o', '.', 'e', 'x', 'e', 0, '.', 't', 'x', 't'};
      String fooStr = new String(foo);
      char[] foo2 = {'C', ':', '\\', 'f', '\\', 'H', 'e', 'l', 'l', 'o', '.', 'e', 'x', 'e', '.', 't', 'x', 't'};
      String fooStr2 = new String(foo2);

      for(int i=0; i<fooStr.length(); i++) {
      System.out.println((int) foo[i]);
      }

      try {
      FileOutputStream file = new FileOutputStream(fooStr, false);
      file.close();
      FileOutputStream file2 = new FileOutputStream(fooStr2, false);
      file2.close();
      } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I can validate the string myself - but I don't write code, I do security code review. I look at a lot of naive code every day. This enhancement would remove an opportunity for a developer to make a serious mistake - actually, for thousands of developers to make thousands of mistakes.

            alanb Alan Bateman
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: