用Python编写具有特定权限的文件

2024-05-19 07:23:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个只允许用户可读写的文件(0600)。

唯一的方法是使用os.open()如下吗?

import os
fd = os.open('/path/to/file', os.O_WRONLY, 0o600)
myFileObject = os.fdopen(fd)
myFileObject.write(...)
myFileObject.close()

理想情况下,我希望能够使用with关键字,以便能够自动关闭对象。有没有更好的方法来做我上面所说的?


Tags: 文件topath方法用户importcloseos
3条回答

更新 各位,虽然我感谢你们的支持,但我自己不得不反对下面我最初提出的解决方案。原因是这样做,会有一段时间,不管多么小,文件确实存在,并且没有适当的权限-这会留下广泛的攻击方式,甚至错误行为。
当然,首先创建具有正确权限的文件是违背正确性的方法,使用Python的with只是一种糖果。

所以,请把这个答案作为“不该做什么”的例子

原始帖子

您可以使用os.chmod代替:

>>> import os
>>> name = "eek.txt"
>>> with open(name, "wt") as myfile:
...   os.chmod(name, 0o600)
...   myfile.write("eeek")
...
>>> os.system("ls -lh " + name)
-rw------- 1 gwidion gwidion 4 2011-04-11 13:47 eek.txt
0
>>>

(注意,在Python中使用八进制的方法是显式的——在它前面加上“0o”,就像在“0o600”中一样)。在Python2.x中,只需编写0600就可以了,但这既有误导性,也不受欢迎。)

但是,如果您的安全性是关键的,那么您可能应该使用os.open创建它,就像您这样,并使用os.fdopenos.open返回的文件描述符中检索Python文件对象。

怎么了?file.close()将关闭文件,即使它是用os.open()打开的。

with os.fdopen(os.open('/path/to/file', os.O_WRONLY | os.O_CREAT, 0o600), 'w') as handle:
  handle.write(...)

这个答案解决了answer by vartec关注的多个问题,特别是umask关注。

import os
import stat

# Define file params
fname = '/tmp/myfile'
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL  # Refer to "man 2 open".
mode = stat.S_IRUSR | stat.S_IWUSR  # This is 0o600.
umask = 0o777 ^ mode  # Prevents always downgrading umask to 0.

# For security, remove file with potentially elevated mode
try:
    os.remove(fname)
except OSError:
    pass

# Open file descriptor
umask_original = os.umask(umask)
try:
    fdesc = os.open(fname, flags, mode)
finally:
    os.umask(umask_original)

# Open file handle and write to file
with os.fdopen(fdesc, 'w') as fout:
    fout.write('something\n')

如果所需的模式是0600,则可以更清楚地将其指定为八进制数0o600。更好的方法是使用stat模块。

即使第一次删除旧文件,仍然可能出现竞争条件。在标志中包含os.O_EXCLos.O_CREAT将阻止创建由于竞争条件而存在的文件。这是一个必要的辅助安全措施,用于防止打开可能已存在并具有潜在提升的mode的文件。在Python 3中,如果文件存在,则会引发带有[Errno 17]的FileExistsError

未能首先将umask设置为00o777 ^ mode可能导致由os.open设置的mode(权限)不正确。这是因为默认的umask通常不是0,它将应用于指定的mode。例如,如果我的原始umask2,即0o002,而我指定的模式是0o222,如果我未能首先设置umask,则结果文件可以具有mode0o220,这不是我想要的。每man 2 open,创建文件的模式为mode & ~umask

尽快将umask还原为其原始值。此获取和设置不是线程安全的,必须在多线程应用程序中使用threading.Lock

有关umask的更多信息,请参阅this thread

相关问题 更多 >

    热门问题