5

Looks like Null Byte Injection is possible in Java apps. see: Is null-byte injection possible in Java filenames?

So how does one protect against it? Inspect all the bytes of the filename for a 0 (zero) byte?

ron
  • 53
  • 1
  • 3

3 Answers3

5

Correct. If you allow untrusted input to affect any part of a filename, then you should apply proper input validation to protect yourself from attacks. You will need to protect yourself against not only null byte injection, but also path traversal and other attacks.

My recommendation is to apply the following checks:

  • Ensure that the filename is not "" (the empty string), "." (the current directory), or ".." (the parent directory).

  • Ensure that the untrusted input does not contain any slashes, as they can be used to separate directories and thus might enable a path traversal attack. To be portable and secure, I suggest you check that it does not contain any instance of File.separatorChar (the directory separator) nor of '/' (as '/' also works as a separator on Windows, even though it is not the value of File.separatorChar).

  • Ensure that the path does not contain any '\0' characters (NUL bytes), as they can be used to mount a nul byte injection attack.

  • Check that the filename corresponds to a normal file, using File.isFile(). The purpose here is to ensure that the file does not correspond to a platform-specific special file.

    For instance, on Windows, the filename PRN is reserved and treated specially: it refers to the printer. Moreover, PRN is interpreted globally: if you access the file \Foo\Bar\PRN, Windows interprets this as referring to the printer (and in general, PRN is special in every directory). There are a range of Windows reserved files like this. You want to make sure the attacker is not tricking you into opening one of these reserved files.

    Note that checking with File.isFile() before opening the file is not atomic in the presence of concurrent updates. Therefore, if there are other processes on the system that might concurrently modify the filesystem and might be influenced by untrusted inputs, this check might not be sufficient: you might want to explicitly check whether the last component of the path matches any of the Windows reserved filenames. Here's the list of Windows reserved filenames I'm aware of: CON, AUX, COM1, COM2, COM3, COM4, LPT1, LPT2, LPT3, PRN, NULL. (I suspect that this list is probably incomplete.)

If you want to see some code from a separate project that contains these sorts of checks, albeit for a slightly different purpose, here's an example.

D.W.
  • 98,420
  • 30
  • 267
  • 572
1

Null byte injection in filenames was fixed in Java 7 update 40 (released around Sept. 2013). So, its been fixed for a while now, but it WAS a problem for over a decade and it was a NASTY vulnerability in Java.

The fix is documented here: JDK-8014846 : File and other classes in java.io do not handle embedded nulls properly

1

Control every input of you application. It's generally better to do a whitelist of good inputs then blacklist the bad ones.(You can easily forget on something in blacklisting, or new attack is discovered which is not blacklisted.) So I recommend checking it against some regular expression which should cover all possible inputs.

Tomáš Šíma
  • 305
  • 1
  • 2
  • 7