2024-05-19 07:23:00 发布
网友
我正在尝试创建一个只允许用户可读写的文件(0600)。
0600
唯一的方法是使用os.open()如下吗?
os.open()
import os fd = os.open('/path/to/file', os.O_WRONLY, 0o600) myFileObject = os.fdopen(fd) myFileObject.write(...) myFileObject.close()
理想情况下,我希望能够使用with关键字,以便能够自动关闭对象。有没有更好的方法来做我上面所说的?
with
更新 各位,虽然我感谢你们的支持,但我自己不得不反对下面我最初提出的解决方案。原因是这样做,会有一段时间,不管多么小,文件确实存在,并且没有适当的权限-这会留下广泛的攻击方式,甚至错误行为。 当然,首先创建具有正确权限的文件是违背正确性的方法,使用Python的with只是一种糖果。
所以,请把这个答案作为“不该做什么”的例子
原始帖子
您可以使用os.chmod代替:
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就可以了,但这既有误导性,也不受欢迎。)
0o
0o600
但是,如果您的安全性是关键的,那么您可能应该使用os.open创建它,就像您这样,并使用os.fdopen从os.open返回的文件描述符中检索Python文件对象。
os.open
os.fdopen
怎么了?file.close()将关闭文件,即使它是用os.open()打开的。
file.close()
with os.fdopen(os.open('/path/to/file', os.O_WRONLY | os.O_CREAT, 0o600), 'w') as handle: handle.write(...)
这个答案解决了answer by vartec关注的多个问题,特别是umask关注。
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模块。
stat
即使第一次删除旧文件,仍然可能出现竞争条件。在标志中包含os.O_EXCL和os.O_CREAT将阻止创建由于竞争条件而存在的文件。这是一个必要的辅助安全措施,用于防止打开可能已存在并具有潜在提升的mode的文件。在Python 3中,如果文件存在,则会引发带有[Errno 17]的FileExistsError。
os.O_EXCL
os.O_CREAT
mode
FileExistsError
未能首先将umask设置为0或0o777 ^ mode可能导致由os.open设置的mode(权限)不正确。这是因为默认的umask通常不是0,它将应用于指定的mode。例如,如果我的原始umask是2,即0o002,而我指定的模式是0o222,如果我未能首先设置umask,则结果文件可以具有mode的0o220,这不是我想要的。每man 2 open,创建文件的模式为mode & ~umask。
0
0o777 ^ mode
2
0o002
0o222
0o220
man 2 open
mode & ~umask
尽快将umask还原为其原始值。此获取和设置不是线程安全的,必须在多线程应用程序中使用threading.Lock。
threading.Lock
有关umask的更多信息,请参阅this thread。
更新 各位,虽然我感谢你们的支持,但我自己不得不反对下面我最初提出的解决方案。原因是这样做,会有一段时间,不管多么小,文件确实存在,并且没有适当的权限-这会留下广泛的攻击方式,甚至错误行为。
当然,首先创建具有正确权限的文件是违背正确性的方法,使用Python的
with
只是一种糖果。所以,请把这个答案作为“不该做什么”的例子
原始帖子
您可以使用
os.chmod
代替:(注意,在Python中使用八进制的方法是显式的——在它前面加上“
0o
”,就像在“0o600
”中一样)。在Python2.x中,只需编写0600
就可以了,但这既有误导性,也不受欢迎。)但是,如果您的安全性是关键的,那么您可能应该使用
os.open
创建它,就像您这样,并使用os.fdopen
从os.open
返回的文件描述符中检索Python文件对象。怎么了?
file.close()
将关闭文件,即使它是用os.open()
打开的。这个答案解决了answer by vartec关注的多个问题,特别是
umask
关注。如果所需的模式是
0600
,则可以更清楚地将其指定为八进制数0o600
。更好的方法是使用stat
模块。即使第一次删除旧文件,仍然可能出现竞争条件。在标志中包含
os.O_EXCL
和os.O_CREAT
将阻止创建由于竞争条件而存在的文件。这是一个必要的辅助安全措施,用于防止打开可能已存在并具有潜在提升的mode
的文件。在Python 3中,如果文件存在,则会引发带有[Errno 17]的FileExistsError
。未能首先将
umask
设置为0
或0o777 ^ mode
可能导致由os.open
设置的mode
(权限)不正确。这是因为默认的umask
通常不是0
,它将应用于指定的mode
。例如,如果我的原始umask
是2
,即0o002
,而我指定的模式是0o222
,如果我未能首先设置umask
,则结果文件可以具有mode
的0o220
,这不是我想要的。每man 2 open
,创建文件的模式为mode & ~umask
。尽快将
umask
还原为其原始值。此获取和设置不是线程安全的,必须在多线程应用程序中使用threading.Lock
。有关umask的更多信息,请参阅this thread。
相关问题 更多 >
编程相关推荐