Python下POSIX系统中安全创建新文件并移走同名文件的方法
在POSIX系统下Python安全创建文件并备份同名文件的方案
核心问题:原代码的TOCTOU漏洞
你给出的代码存在**时间检查到时间使用(TOCTOU)**漏洞:os.path.exists()检查文件存在性后,到执行os.move()和open()的间隙中,其他进程可能创建/删除该文件,导致逻辑异常。
标准库解决方案(无第三方依赖)
利用POSIX文件系统的原子操作特性,结合Python标准库的API实现安全流程:
方案步骤
- 尝试原子创建新文件:使用Python 3.3+支持的
"x"模式打开文件,该模式对应POSIX的O_CREAT | O_EXCL标志,会原子性地检查文件是否存在并创建——若文件已存在则抛出FileExistsError,否则直接创建并打开文件。 - 处理文件已存在的情况:捕获
FileExistsError后,用os.replace()原子性地将原文件移至备份路径(POSIX下os.replace()是原子操作,避免移动过程中被其他进程干扰)。 - 再次原子创建文件:移动完成后,再次用
"x"模式创建文件,确保此时没有其他进程抢先创建该文件。
代码实现
import os name_of_file = "target.txt" backup_name = "target_backup.txt" def create_file_with_backup(): try: # 原子创建文件,若存在则报错 with open(name_of_file, "x") as f: # 在这里写入文件内容 f.write("new content\n") return except FileExistsError: # 原子移动原文件到备份路径 # 注意:若backup_name已存在,os.replace()会直接覆盖它,若需要避免可先检查或用唯一备份名(如带时间戳) os.replace(name_of_file, backup_name) # 再次尝试原子创建 with open(name_of_file, "x") as f: f.write("new content\n") create_file_with_backup()
关键细节
"x"模式的原子性:完全由操作系统保证检查和创建的原子性,杜绝TOCTOU漏洞。os.replace()的原子性:POSIX系统下,该操作会原子地将源文件重命名为目标路径,即使跨文件系统也能保证操作的原子性(相比os.rename()更可靠)。- 备份路径的唯一性:如果担心备份路径已存在,可生成带时间戳或随机字符串的唯一备份名(如
f"target_backup_{time.time()}.txt"),避免覆盖已有备份。
补充说明
如果需要更复杂的文件操作逻辑,标准库的tempfile模块可用于临时文件的安全处理,但上述方案已能覆盖绝大多数场景,无需第三方包。
内容的提问来源于stack exchange,提问作者James Tocknell
相关产品推荐
相关产品推荐

