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.
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.
- duplicates
-
JDK-8003992 File and other classes in java.io do not handle embedded nulls properly
-
- Closed
-