Java中有没有办法安全地写出临时文件?
据我所知,创建临时文件(createTempFile)的唯一方法实际上并不是同时打开它,因此文件打开和放置之间存在竞争条件。文件写。我错过了什么吗?我在UnixFileSystem.java中找不到createFileExclusively(String)背后的C源代码,但是我怀疑它真的可以做任何事情,因为在创建临时文件后文件打开发生在Java代码中(除非它试图做一些事情文件锁?)。
问题
在创建临时文件之间&你打开它,恶意攻击者可以取消链接该临时文件&在那里放恶意的东西。例如,攻击者可以创建命名管道来读取敏感数据。或者类似地,如果您最终通过读取文件来复制文件,那么命名管道可能会忽略所写的所有内容。提供要阅读的恶意内容。
我记得在过去的10多年中读过许多临时文件攻击的例子,这些例子利用了名称出现在命名空间和文件实际打开之间的竞争条件。
希望减轻因素是Java设置正确的umask,因此权限较低的用户无法读取/写入文件,通常/ tmp目录会正确限制权限,因此您无法执行取消链接攻击。 / p>
当然,如果您为受到攻击的权限较低的用户所拥有的临时文件传递自定义目录,则该用户可能会对您进行取消链接攻击。地狱,使用inotify,利用竞争条件可能比进行目录列表的暴力循环更容易。
答案 0 :(得分:1)
http://kurt.seifried.org/2012/03/14/creating-temporary-files-securely/
爪哇
使用java.io.File.createTempFile() - http://www.veracode.com/blog/2009/01/how-boring-flaws-become-interesting/
的一些有趣信息对于目录,在How to create a temporary directory/folder in Java?
上有一个有用的帖子Java 7
对于文件使用java.io.File.createTempFile()
目录的使用createTempDirectory()
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html
答案 1 :(得分:0)
请记住,在许多系统上,仅仅因为文件没有名称并不意味着它无法访问。例如,在Linux上,/proc/<pid>/fd/<fdno>
中提供了打开文件描述符。因此,即使有人知道/有对打开文件的引用,您也应确保使用临时文件是安全的。
如果您准确指定了要阻止的攻击类别,则可能会得到更有用的答案。
答案 2 :(得分:0)
防范其他普通用户ID?是的,在任何正常运行的多用户系统上。
保护您自己的用户标识或超级用户?否。
答案 3 :(得分:0)
从Java 7开始,我们有OpenOption
。
配置如何打开或创建文件的对象。
打开或创建文件时,此类对象由
newOutputStream
,newByteChannel
,FileChannel.open
和AsynchronousFileChannel.open
等方法使用。
特别感兴趣的是StandardOpenOptions.CREATE_NEW
。
创建新文件,如果文件已存在则失败。检查文件是否存在以及文件的创建(如果不存在)与其他文件系统操作相比是原子的。
所以,你可以这样做:
FileChannel mkstemp() {
Path path = Files.createTempFile(null, null);
Files.delete(path);
return FileChannel.open(path, WRITE, CREATE_NEW);
}
实现相同的模板行为留给读者练习。