可以使用競態條件繞過 Samba 安全設置“寬連結”嗎?
Apache 有選項
FollowSymLinks
和SymLinksIfOwnerMatch
. 但是,它們“不應被視為安全限制,因為符號連結測試受制於使其可以規避的競爭條件。” 將其與 Samba 進行比較:Samba 有一個選項叫做
wide links
:注意:啟用 UNIX 擴展時打開此參數將允許 UNIX 客戶端在共享上創建符號連結,該連結可以指向共享定義導出的受限路徑之外的文件或目錄。這可能會導致訪問共享之外的區域。由於這個問題,如果該
unix extensions
選項打開,此參數將被自動禁用(在日誌文件中顯示一條消息)。
allow insecure wide links
如果您希望更改兩個參數之間的這種耦合,請參閱參數。可以通過競態條件繞過 Samba 選項嗎?
如果不是,Samba 如何防止競爭條件?例如,可以使用什麼操作順序來防止競爭條件?
它當然是脆弱的。請參閱CVE-2017-2619。
此錯誤的更新檔包括一個新功能,稱為
open_dir_safely()
. 它用於chdir()
進入包含要打開的文件的目錄。我想這意味著您可以使用
getcwd()
, 來檢查您是否仍在 Samba 共享目錄中。至少這在 Linux 上可以很好地工作,因為它有一個有效的系統呼叫getcwd()
. 我還沒有確切地確認 Samba 之後做了什麼chdir()
。如果您的程序有多個執行緒,這不是很好,因為
chdir()
會影響整個程序:-)。Linux 特定程序可以改為使用open()
該O_PATH
標誌,然後readlink()
在/proc/self/fd/
.以上可以為包含該文件的目錄提供保證。為確保將文件名傳遞給 時不會將其解析為連結
open()
,您可以使用該O_NOFOLLOW
標誌。如果是符號連結,open()
將返回ELOOP
. 然後您可以readlink()
自己處理文件並解析符號連結。這將涉及從一開始就重複該過程:-)。如果您必須重複該過程“太多”次,那麼您可以返回失敗(
ELOOP
再次)。(如果您必須重試太多次,因為有人在玩愚蠢的乞丐並在open(... O_NOFOLLOW)
和 之間反復更改文件,情況也是如此readlink()
)。在非 Linux 作業系統上,您可能沒有非常高效的
getcwd()
. 如果你有,那麼你可以通過遍歷路徑的每一段,使用+並手動解析連結O_PATH
來避免。getcwd()``O_PATH``O_NOFOLLOW
將來,這個問題可能會通過一些特定的標誌來解決,例如AT_PATH_BENEATH 或 O_BENEATH。