在 vi、nvi 和 vim 中編輯敏感文件時禁止恢復文件

在 vi、nvi 和 vim 中編輯敏感文件時禁止恢復文件

我正在編寫一個應用程序,該應用程式維護一個加密資料庫,其中包含極其敏感的信息,包括加密密鑰和密碼。該應用程式偏執於使用memlock、阻止ptrace、防止coredumps等,但有一個命令可以讓資料庫所有者編輯資料庫的內容。該命令將整個資料庫以人類可讀的 ASCII 格式寫入臨時文件,並允許使用者對其進行編輯。具體來說,它在新創建的目錄/tmp/XXXXXXXX/(其中 /tmp 理想情況下是內存檔案系統)中創建一個新文件,然後在該文件上運行用戶首選的編輯器。當編輯器退出時,應用程式會解析檔案內容並粉碎檔案和下面的任何其他內容,/tmp/XXXXXXXX/然後最終刪除目錄。

不幸的是,這種策略對於任何vi 變體都不能很好地工作,因為編輯器最終會將文件的副本寫入/var/tmp/vi.recover,即使在vi 刪除它們之後,它們也可能會保留在磁碟上。 (數據包含高價值的私鑰,可以輕鬆搜索整個原始分區。)我正在尋找一種通用方法來抑制這些恢復文件,或者至少將它們移動到/tmp/XXXXXXXX/.

我的理想解決方案適用於大多數 vi 變體,但我也很高興解析EDITOR環境變數並為每個編輯器做不同的事情。因此,如果您有一個適用於 vim 但不適用於其他系統的解決方案,那麼這至少是一個好的開始。 (我已經對 vim 進行了特殊處理,以重新打開編輯器到解析錯誤的確切列號,而其他 vi 變體只能打開到適當的行。)

因為這是一個要分發給其他人的應用程序,所以我不能做的一件事就是透過編輯人們的 .exrc 或 .vimrc 檔案來解決問題。在絕對緊要關頭,我想我可以在執行編輯器之前更改 HOME 環境變量,並創建一個臨時 .vimrc,將用戶的真實變量與一些恢復抑制命令合併。但是,我更喜歡命令列或註釋解決方案。

我能得到的最接近的最小工作範例是分享我對 emacs 所做的事情,即在文件末尾附加以下註釋:

# Local Variables:
# make-backup-files: nil
# auto-save-default: nil
# End:

雖然最簡單的是命令列選項,但如果某些等效的註釋可以適用於 vim 或任何其他 vi 變體,那就太好了。

更新:

經過 strace 的一些實驗,似乎有以下指令可能為 vim 做我想做的事:

vim -n -c 'set viminfo=' /tmp/XXX/secret.ini

但是,它不適用於--cmd,這是建議的選項,但僅適用於-c。此外,我不太明白-n是什麼,但只是注意到手冊頁說它將破壞恢復。所以我仍然很想聽到了解 vim 的人的回答,如果這確實有效的話。當然,其他 vi 變體的解決方案也將受到歡迎。

更新2:

EXINIT 環境變數可能如果我將其設為 ,則適用於 vi 和 nvi EXINIT=set dir=/tmp/XXX|set recdir=。 nvi 會在啟動時發出有關無法恢復的警告,這是令人鼓舞的,而 vi 確實會將檔案放入檔案系統中,但至少它們位於 /tmp 中,而 /tmp 通常是記憶體檔案系統。

答案1

vim可以使用以下命令移動恢復檔案的位置directory選項

set directory=/tmp/XXXXXXXX

可以將其新增至單一實例的命令列中,如下所示

mkdir -m700 /tmp/xyz
vim --cmd "set directory=/tmp/xyz" /path/to/secure.file

答案2

我可以想到幾種選擇來為用戶提供一個盡可能偏執的合理編輯器。由於這是一個安全敏感的應用程序,請對此處的所有內容持保留態度,並糾正任何錯誤。

我建議將其中一項作為預設操作,但以清晰記錄的方式讓人們可以使用自己的vim作為清晰記錄的選項,這樣他們就不會嘗試將資料複製出鎖定的vi.

此外,其中一些建議(特別是與 混淆LD_PRELOAD)可能在您的環境中完全不可接受、已停用(盡可能)或受到限制。

以下是一些可能相互排斥的選項(排名不分先後),

  1. 像這樣以非特權使用者身分執行編輯器sudoedit
  2. 為您自己的編輯器提供您不想修補或編譯的功能
  3. libc使用 攔截對有問題的函數的呼叫LD_PRELOAD
  4. 完全跳過使用者.vimrc

1)以非特權使用者身分執行編輯器

如果您有能力創建其他用戶或要求使用該軟體的人創建專用的非特權用戶,那麼您可以使用相同的技巧sudoedit:創建臨時文件並讓用戶作為非特權用戶對其進行編輯。我不知道如何保證臨時文件永遠不會接觸磁碟。

聽起來您已經在做類似的事情,但沒有非特權用戶。

這是一個超級用戶回答解釋瞭如何sudoedit工作

另外,我建議研究一下它sudoedit的功能是如何sudo運作的。這是一些相關程式碼

2)捆綁你自己的vi.

nvi它很小並且獲得了 BSD 許可,您也許可以對其進行修補,使其永遠不會創建交換文件或在沒有交換文件支援的情況下編譯它。我實際上不知道,因為我上次嘗試構建時nvi無法弄清楚如何獲取其古老版本的自動工具來檢測 OS X。

作為主要產品建置的一部分,您可以獲得nvi可執行檔案的雜湊值並將其作為建置時間常數烘焙。

Emacs 用戶可以獲得mg.這是一個連結到 mg 的分叉。實際上存在於 OpenBSD 原始碼樹中的變體是 ISC 許可的。您可能需要修補它,因為它有時會崩潰(例如,與 互動cscope)。

我認為 Nano 用戶運氣不好。

3)LD_PRELOAD

用於LD_PRELOAD直接ld.so(在 Linux 上)載入填充程式以攔截對、 、 &clibc等函數的呼叫。fwritefork

4) 跳過使用者的配置選項vim,運行您自己的最小配置。

這是我能想到的最安全的命令行vim,但我可能錯過了一些東西。我只是透過閱讀 vim 手冊頁並查看我的.vimrc.

  • -u NONE-- 沒有初始化
  • -i NONE- 不.viminfo
  • -U NONE-- 沒有初始化(gvim但是嘿,你永遠不能太小心)
  • -Z - 開始就像你argv[0]一樣rvim
  • set nocompatible——vi不相容。
  • set backspace=indent,eol,start-- 讓退格鍵更直觀
  • set noexrc-- 可能是多餘的,不要讀取任何rc檔案。
  • set secure-- no autocmd, no shell, no write, display --map指令。
  • set nobackup-- 沒有備份選項
  • set laststatus=2-- 顯示您正在編輯的文件

因此,這是將所有內容組合在一起的命令列。

vim -n -u NONE -i NONE -U NONE -Z \
        --cmd "set nocompatible | set backspace=indent,eol,start | set noexrc | set secure | set nomodeline | set nobackup | set laststatus=2" \
         --

相關內容