在 vi、nvi 和 vim 中编辑敏感文件时禁止恢复文件

在 vi、nvi 和 vim 中编辑敏感文件时禁止恢复文件

我正在编写一个应用程序,该应用程序维护一个加密数据库,其中包含极其敏感的信息,包括加密密钥和密码。该应用程序偏执于使用 memlock、阻止 ptrace、防止 coredump 等,但有一个命令可以让数据库所有者编辑数据库的内容。该命令将整个数据库以人类可读的 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" \
         --

相关内容