JDK-8011539 : File APIs Should Not Allow Null Bytes
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • Submitted: 2013-04-04
  • Updated: 2013-09-12
  • Resolved: 2013-09-12
Related Reports
Duplicate :  
Description
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.