gpt4 book ai didi

python - 当且仅当 Python 不存在文件时,才安全地创建文件

转载 作者:IT老高 更新时间:2023-10-28 21:11:36 25 4
gpt4 key购买 nike

我希望根据文件是否已经存在来写入文件,仅在文件不存在时写入(实际上,我希望继续尝试文件,直到找到不存在的文件)。

以下代码显示了一种潜在的攻击者可以插入符号链接(symbolic link)的方法,正如 this post 中所建议的那样。在文件测试和正在写入的文件之间。如果代码以足够高的权限运行,这可能会覆盖任意文件。

有没有办法解决这个问题?

import os
import errno

file_to_be_attacked = 'important_file'

with open(file_to_be_attacked, 'w') as f:
f.write('Some important content!\n')

test_file = 'testfile'

try:
with open(test_file) as f: pass
except IOError, e:

# Symlink created here
os.symlink(file_to_be_attacked, test_file)

if e.errno != errno.ENOENT:
raise
else:
with open(test_file, 'w') as f:
f.write('Hello, kthxbye!\n')

最佳答案

编辑:另见Dave Jones' answer : 从 Python 3.3 开始,你可以使用 x 标志到 open() 来提供这个功能。

原答案如下

是的,但不使用 Python 的标准 open() 调用。您需要使用 os.open()相反,它允许您为底层 C 代码指定标志。

特别是,您想使用 O_CREAT | O_EXCL。从我的 Unix 系统上 O_EXCL 下的 open(2) 手册页:

Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT, and pathname already exists, then open() will fail. The behavior of O_EXCL is undefined if O_CREAT is not specified.

When these two flags are specified, symbolic links are not followed: if pathname is a symbolic link, then open() fails regardless of where the symbolic link points to.

O_EXCL is only supported on NFS when using NFSv3 or later on kernel 2.6 or later. In environments where NFS O_EXCL support is not provided, programs that rely on it for performing locking tasks will contain a race condition.

所以它并不完美,但 AFAIK 是您可以避免这种竞争条件的最接近的方法。

编辑:使用 os.open() 而不是 open() 的其他规则仍然适用。特别是,如果您想使用返回的文件描述符进行读取或写入,您将需要 O_RDONLYO_WRONLYO_RDWR 标志之一也是。

所有 O_* 标志都在 Python 的 os 模块中,因此您需要 import os 并使用 os。 O_CREAT

示例:

import os
import errno

flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY

try:
file_handle = os.open('filename', flags)
except OSError as e:
if e.errno == errno.EEXIST: # Failed as the file already exists.
pass
else: # Something unexpected went wrong so reraise the exception.
raise
else: # No exception, so the file must have been created successfully.
with os.fdopen(file_handle, 'w') as file_obj:
# Using `os.fdopen` converts the handle to an object that acts like a
# regular Python file object, and the `with` context manager means the
# file will be automatically closed when we're done with it.
file_obj.write("Look, ma, I'm writing to a new file!")

关于python - 当且仅当 Python 不存在文件时,才安全地创建文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10978869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com