防止检查时间到使用时间?
Protecting against Time-of-check to time-of-use?
我正在阅读:https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
他们证明这段代码有问题,我完全理解为什么会这样:
if (access("file", W_OK) != 0) {
exit(1);
}
// Attacker: symlink("/etc/passwd", "file");
fd = open("file", O_WRONLY);
// Actually writing over /etc/passwd
write(fd, buffer, sizeof(buffer));
但真正的问题是如何防范此类攻击?
您可以使用 O_NOFOLLOW
标志。如果路径的 basename
是符号 link,它将导致 open
失败。这将解决所描述的攻击。
要覆盖目录路径中的 links,您可以检查 frealpath(fd, ...)
是否符合您的预期。
另一种防止进程覆盖 /etc/passwd
的方法是 运行 它作为非根用户,这样它就没有权限。或者,您可以使用 chroot - 或者更一般地说,一个容器 - 来防止主机系统的 /etc/passwd
对进程可见。
更一般地说,文件系统 TOCTOU 目前无法在 Linux 上解决。您需要在文件系统或系统调用级别上提供事务支持——这是目前所缺乏的。
没有万无一失的解决方案。
还要注意 Rice's theorem。它可能是相关的。
但是您可以采用系统范围的约定(并记录下来),即访问给定文件的每个程序都使用 flock(2).
之类的锁定工具
我正在阅读:https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use
他们证明这段代码有问题,我完全理解为什么会这样:
if (access("file", W_OK) != 0) {
exit(1);
}
// Attacker: symlink("/etc/passwd", "file");
fd = open("file", O_WRONLY);
// Actually writing over /etc/passwd
write(fd, buffer, sizeof(buffer));
但真正的问题是如何防范此类攻击?
您可以使用 O_NOFOLLOW
标志。如果路径的 basename
是符号 link,它将导致 open
失败。这将解决所描述的攻击。
要覆盖目录路径中的 links,您可以检查 frealpath(fd, ...)
是否符合您的预期。
另一种防止进程覆盖 /etc/passwd
的方法是 运行 它作为非根用户,这样它就没有权限。或者,您可以使用 chroot - 或者更一般地说,一个容器 - 来防止主机系统的 /etc/passwd
对进程可见。
更一般地说,文件系统 TOCTOU 目前无法在 Linux 上解决。您需要在文件系统或系统调用级别上提供事务支持——这是目前所缺乏的。
没有万无一失的解决方案。
还要注意 Rice's theorem。它可能是相关的。
但是您可以采用系统范围的约定(并记录下来),即访问给定文件的每个程序都使用 flock(2).
之类的锁定工具