I am interested in images but the question is quite general. I am doing it thusly :
private static final SecureRandom RANDOM = new SecureRandom();
private static final int FILENAMElENGTH = 73; // a guess
private static String nextId() { // synchronized ?
return new BigInteger(FILENAMElENGTH, RANDOM).toString(32);
} // https://stackoverflow.com/a/41156/281545
Questions :
I understand that keeping the original filename, the username etc can lead to security holes
Related :
static File getImageFile() throws IOException {
return File.createTempFile("upload_", ".jpg", new File(upload_path));
}
// String filename = getImageFile().getName();
This is guaranteed to be unique (docs) - and it is not a tmp file at all (provided you have control to the upload_path
, which must be a path to an existing directory (although the docs are not explicit about this)).
Obviously you should have a better way to specify the extension but this is another question.
No session ids, user input etc.
Got the idea from a BalusC blog post :
It is necessary to know the file upload location in the MultipartMap as well, because we can then make use of File#createTempFile() to create files with an unique filename to avoid them being overwritten by another file with a (by coincidence) same name. Once you have the uploaded file at hands in the servlet or bean, you can always make use of File#renameTo() to do a fast rename/move.
Notice that createTempFile
used to be rather insecure before Java 6.11 (see here for an exposition and here for a general exposition of tmp files security). Also see this SO question - there is a window of vulnerability between file creation and opening. These issues however have nothing to do with filenames - still createTempFile
is the only way to guarantee uniqueness (I hope you are using latest JDK, to avoid the predictable filenames createTempFile
suffered from).