如何防范Time-of-check to time-of-use(TOCTOU)竞态条件漏洞?
TOCTOU漏洞防范手段
TOCTOU(检查时间到使用时间)漏洞的核心成因是资源校验和资源使用两个操作不具备原子性,中间的时间差可被攻击者篡改目标资源,针对你给出的文件操作类TOCTOU场景,可采取以下防范手段:
- 取消独立的前置权限校验,先拿文件描述符再做校验
示例中的漏洞根源是access()和open()两次基于文件名的操作存在时间窗口,最优解法是直接调用open获取文件描述符,所有后续校验、读写操作都基于该文件描述符执行,完全消除两次文件名查询的时间差。 - 打开文件时传入安全标识阻断符号链接利用
调用open时添加O_NOFOLLOW参数,如果目标路径是符号链接会直接返回错误,直接阻断攻击者将目标文件替换为指向/etc/passwd等敏感文件的符号链接的利用路径。如果操作的是目录,还可搭配O_DIRECTORY参数确保打开的是预期目录。 - 用基于文件描述符的系统调用替代基于文件名的调用
打开文件后,所有后续的属性查询、权限校验都使用传入文件描述符的接口,比如用fstat替代stat、用faccessat替代access,确保所有操作针对的都是同一个已经打开的文件对象,不会被攻击者替换路径指向的资源。 - 修复后的参考代码示例:
// 直接打开文件,禁止跟随符号链接 fd = open("file", O_WRONLY | O_NOFOLLOW); if (fd < 0) { exit(1); } // 基于已获取的文件描述符做权限校验 if (faccessat(fd, NULL, W_OK, AT_EMPTY_PATH) != 0) { close(fd); exit(1); } write(fd, buffer, sizeof(buffer)); close(fd);
- 启用系统层面的安全防护机制
开启操作系统自带的符号链接保护规则,比如Linux系统下设置fs.protected_symlinks = 1内核参数,禁止普通用户在全局可写目录创建指向特权文件的符号链接,从系统层面缩小攻击面。 - 优先使用原子操作完成资源操作
所有涉及文件系统资源判断+修改的逻辑,尽量使用原子性的系统调用实现,比如创建独占文件时使用open(O_CREAT | O_EXCL)原子完成判断+创建操作,不要拆分为「判断文件是否存在」和「创建文件」两个独立步骤。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

