6

Java中有什么方法可以安全地写出临时文件吗?

据我所知,创建临时文件(createTempFile)的唯一方法实际上不会同时打开它,因此文件打开和文件写入之间存在竞争条件。我错过了什么吗?我在 UnixFileSystem.java 中找不到 createFileExclusively(String) 背后的 C 源代码,但我怀疑它真的可以做任何事情,因为在创建临时文件后,文件打开发生在 Java 代码中(除非它尝试用文件锁?)。

问题

在创建临时文件和打开它之间,恶意攻击者可以取消该临时文件的链接并将恶意内容放在那里。例如,攻击者可以创建命名管道来读取敏感数据。或者类似地,如果您最终通过读取文件来复制文件,那么命名管道可能会忽略所有写入的内容并提供要读取的恶意内容。

我记得在过去 10 多年中阅读过大量临时文件攻击示例,这些示例利用名称出现在命名空间中和文件实际打开时之间的竞争条件。

希望缓解因素是 Java 正确设置了 umask,因此权限较低的用户无法读取/写入文件,并且 /tmp 目录通常会正确限制权限,因此您无法执行取消链接攻击。

当然,如果您为受感染的低权限用户拥有的临时文件传递自定义目录,则该用户可能会对您进行取消链接攻击。地狱,使用inotify,利用竞争条件可能比仅仅执行目录列表的蛮力循环更容易。

4

4 回答 4

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/

对于目录,如何在 Java 中创建临时目录/文件夹?

爪哇 7

对于文件使用 java.io.File.createTempFile()

对于目录使用 createTempDirectory()

http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html

于 2012-09-24T18:45:23.047 回答
0

对其他普通用户名安全吗?是的,在任何正常运行的多用户系统上。

保护您自己的用户 ID 或超级用户?不。

于 2012-06-19T22:34:02.853 回答
0

请记住,在许多系统上,仅仅因为文件没有名称并不意味着它是不可访问的。例如,在 Linux 上,打开的文件描述符在/proc/<pid>/fd/<fdno>. 因此,即使有人知道/有对打开文件的引用,您也应该确保您对临时文件的使用是安全的。

如果您准确指定您要阻止的攻击类别,您可能会得到更有用的答案。

于 2012-04-18T02:10:53.773 回答
0

从 Java 7 开始,我们拥有OpenOption.

配置如何打开或创建文件的对象。

这种类型的对象由诸如newOutputStreamnewByteChannelFileChannel.openAsynchronousFileChannel.open打开或创建文件之类的方法使用。

特别感兴趣的是StandardOpenOptions.CREATE_NEW.

创建一个新文件,如果文件已经存在则失败。检查文件是否存在以及如果文件不存在则创建文件对于其他文件系统操作而言是原子操作。

因此,您可以执行以下操作:

FileChannel mkstemp() {
    Path path = Files.createTempFile(null, null);
    Files.delete(path);
    return FileChannel.open(path, WRITE, CREATE_NEW);
}

实现相同的模板行为留给读者作为练习。

于 2016-08-02T11:10:33.743 回答