首頁 > 軟體

使用fdopen實現對Python程序產生的檔案進行許可權最小化設定

2023-11-03 10:00:22

需求背景

用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操作刪除原檔案後再進行新的檔案操作,避免檔案許可權被覆蓋或者重用,從而導致建立的新檔案許可權設定與我們所預期的不符合。

到此這篇關於使用fdopen實現對Python程序產生的檔案進行許可權最小化設定的文章就介紹到這了,更多相關Python檔案許可權最小化設定內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com