使用fdopen实现对Python进程产生的文件进行权限最小化配置
作者:DECHIN 发布时间:2021-04-20 15:49:05
需求背景
用python进行文件的创建和读写操作时,我们很少关注所创建的文件的权限配置。对于一些安全性较高的系统,如果我们创建的文件权限其他用户或者同一用户组里的其他用户有可读权限的话,有可能导致不必要的信息泄漏的风险。因此,除了创建一个更加安全和隐私的个人环境之外(如容器环境等),我们还可以对生成的文件的配置进行权限最小化处理。
常用方法及其缺陷分析
常用的python文件创建和读写方法,是直接通过内置的open函数创建一个文件。这里如果是使用with语法来创建的,结束语句后会自动关闭被打开的对象。而如果是直接使用open函数来定义一个对象,则需要在任务结束时手动的执行close操作。以下演示内置函数open的用法及其文件操作属性,首先创建一个名为file-test.py的文件:
# file-test.py
with open('test1.txt', 'w') as file:
file.write('hello world!')
该任务的内容为:在当前目录下创建一个名为test1.txt的文件,清空该文件的内容后,在文件中写入hello world!这个字符串。接下来用python3执行该文件:
[dechin@dechin-manjaro os_security]$ python3 file-test.py
[dechin@dechin-manjaro os_security]$ ll
总用量 8
-rw-r--r-- 1 dechin dechin 83 1月 25 13:43 file-test.py
-rw-r--r-- 1 dechin dechin 12 1月 25 13:43 test1.txt
这里我们发现,在执行之后成功产生了test1.txt这个文件,其权限配置为644,与前面创建的file-test.py保持一致。在不清楚内置函数open的实现原理时,原本以为这个产生的文件权限配置是与当前的py文件保持一致的。然而经过进一步的测试,将py文件的权限配置为440之后再重新执行该文件:
[dechin@dechin-manjaro os_security]$ chmod 440 file-test.py
[dechin@dechin-manjaro os_security]$ ll
总用量 8
-r--r----- 1 dechin dechin 83 1月 25 13:43 file-test.py
-rw-r--r-- 1 dechin dechin 12 1月 25 13:43 test1.txt
[dechin@dechin-manjaro os_security]$ rm test1.txt
[dechin@dechin-manjaro os_security]$ python3 file-test.py
[dechin@dechin-manjaro os_security]$ ll
总用量 8
-r--r----- 1 dechin dechin 83 1月 25 13:43 file-test.py
-rw-r--r-- 1 dechin dechin 12 1月 25 13:44 test1.txt
这里从测试结果我们可以看出,python的内置函数open产生的文件类型是与源py文件无关的。关于这里py文件的执行是否需要可执行权限,可以参考这篇博客。
改进后的python文件创建方法
通过fdopen这个库以及特殊的权限指定,我们可以设置生成文件的访问权限,以下直接展示一个python代码案例:
# fdopen-test.py
import os
import stat
file_name = 'test2.txt'
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
mode = stat.S_IRUSR | stat.S_IWUSR
with os.fdopen(os.open(file_name, flags, mode), 'w') as file:
file.write('hello world!')
执行之后我们可以发现,当前目录下生成了一个名为test2.txt的文件,其权限配置为600, 对照于我们在代码中设置的mode = stat.S_IRUSR | stat.S_IWUSR。这里我们先对其中的一些参数作一个解释:os.O_WRONLY表示以只写的方式打开,os.O_CREAT表示创建并打开一个新文件,os.O_EXCL表示如果文件已存在则报错。而mode中所配置的权限分别对应rwx配置,其中USR,GRP,OTH又分别对用户、用户组、其他用户进行了细分的配置,从而我们就可以通过改变mode参数来实现所有种类的权限配置。
我们可以尝试将上述用例中的mode作一个调整,比如添加一个可执行权限变为700:
# fdopen-test.py
import os
import stat
file_name = 'test3.txt'
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
with os.fdopen(os.open(file_name, flags, mode), 'w') as file:
file.write('hello world!')
又或者,我们需要为用户组里的其他用户添加可访问权限,比如640权限:
# fdopen-test.py
import os
import stat
file_name = 'test4.txt'
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP
with os.fdopen(os.open(file_name, flags, mode), 'w') as file:
file.write('hello world!')
甚至我们也可以写出系统原生的644文件权限:
# fdopen-test.py
import os
import stat
file_name = 'test5.txt'
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
with os.fdopen(os.open(file_name, flags, mode), 'w') as file:
file.write('hello world!')
最后,让我们一起看下上面这些python示例执行后得到的结果:
[dechin@dechin-manjaro os_security]$ ll
总用量 28
-rw-r--r-- 1 dechin dechin 269 1月 25 14:58 fdopen-test.py
-r--r----- 1 dechin dechin 84 1月 25 14:11 file-test.py
-rw-r--r-- 1 dechin dechin 12 1月 25 13:44 test1.txt
-rw------- 1 dechin dechin 12 1月 25 14:44 test2.txt
-rwx------ 1 dechin dechin 12 1月 25 14:48 test3.txt
-rw-r----- 1 dechin dechin 12 1月 25 14:56 test4.txt
-rw-r--r-- 1 dechin dechin 12 1月 25 14:58 test5.txt
从结果中我们可以看出,所有产生的文件test*.txt都按照我们预期的文件权限配置生成,到这里我们就完成了所有预期的目标。
总结概要
使用python进行文件的创建和读写时,常规的内置函数open得到的结果会是一个644权限的文件,这不一定能够满足很多对安全性需求较高的执行环境的要求。因此我们可以通过fdopen来对所创建的文件进行进一步的权限约束,具体的操作方法可以在mode中定义一系列的权限配置,比如带有USR的表示当前用来执行python文件的用户,带有GRP的表示用来执行python文件的整个用户组,而OTH则表示其他的所有的用户。这当中尤其是OTH这个选项往往是不必要开放的权限,我们也可以根据具体的场景需求对创建的文件权限进行配置。这里还有一点补充介绍的是,os.O_EXCL这个指令的开启表示如果存在同名文件就无法创建,需要先使用os.remove操作删除原文件后再进行新的文件操作,避免文件权限被覆盖或者重用,从而导致创建的新文件权限配置与我们所预期的不符合。
来源:https://www.cnblogs.com/dechinphy/p/fdopen.html


猜你喜欢
- 这篇文章主要介绍了django自定义模板标签过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 本文实例为大家分享了微信小程序上传图片到php服务器的具体代码,供大家参考,具体内容如下js代码如下 submitPhoto(){ var
- 数据库的数据量达到一定程度之后,为避免带来系统性能上的瓶颈。需要进行数据的处理,采用的手段是分区、分片、分库、分表。一、什么是mysql分表
- 1.%格式符name = '李四'age = 18a = "姓名:%s,年龄:%s"%(name,age
- 应用场景在嵌入式开发中,常常需要将一个binary文件分割成多个文件,或者将一个binary的某块区域抓成一个单独文件。本篇blog以pyt
- 1、查看数据库中有哪些用户? select username from all_users;2、查看数据库中有哪些DBA用户? select
- 一、图的定义图是一种比树更复杂的一种数据结构,在图结构中,结点之间的关系是任意的,任意两个元素之间都可能相关,因此,它的应用极广。图中的数据
- 本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息。分享给大家供大家参考,具体如下:import timefro
- functools模块是Python的标准库的一部分,它是为高阶函数而实现的。高阶函数是作用于或返回另一个函数或多个函数的函数。一般来说,对
- 本文实例讲述了Python使用scipy模块实现一维卷积运算。分享给大家供大家参考,具体如下:一 介绍signal模块包含大量滤波函数、 *
- where条件表达式--统计函数Select count(1) from student;--like模糊查询--统计班上姓张的人数sele
- RegExp就是建立正则的对像。如:Set regEx = New RegExp regE
- 首先预览一下 PyCharm 在实际应用中的界面:(更改了PyCharm的默认风格)安装首先去下载最新的pycharm 2.7.3,进行安装
- 连续看到几个和 Oracle 优化器隐含参数 _sort_elimination_cost_ratio 相关的优化案例(Refer Refe
- 使用本Activation code需要jetbrains-agent支持!插件Activation code:06KU174Y5C-eyJ
- mutation.js代码:changeRoute(state, val) { let routeList = s
- 前言个人一直觉得对学习任何知识而言,概念是相当重要的。掌握了概念和原理,细节可以留给实践去推敲。掌握的关键在于理解,通过具体的实例和实际操作
- 前言在使用PC时与PC交互的主要途径是看屏幕显示、听声音,点击鼠标和敲键盘等等。在自动化办公的趋势下,繁琐的工作可以让程序自动完成。比如自动
- Python语言的崛起让大家对web、爬虫、数据分析、数据挖掘等十分感兴趣。数据挖掘就业前景怎么样?关于这个问题的回答,大家首先要知道什么是
- 开始第一篇。老规矩,先无聊的谈论天气一类的话题。十一长假,天气也终于开始有些秋天的味道,坐在屋里甚至觉得需要热咖啡。话说两年前也是在国庆假期