43.22 安全注意事项

与任何应用程序一样,Emacs 可运行在安全环境中,由操作系统强制执行访问等相关规则。通过谨慎配置,基于 Emacs 的应用也可成为检查此类规则的安全边界的一部分。尽管 Emacs 的默认设置适用于典型软件开发环境,但在存在不可信用户(可能包含攻击者)的环境中,可能需要进行调整。以下汇总了一些安全问题,若你正在开发此类应用,可能会有所帮助。这份清单远非完整,其目的是让你了解相关安全问题,而非作为安全核查清单。

File local variables

Emacs 访问的文件可以包含变量设置,这些设置会影响访问该文件的缓冲区;See 文件局部变量。 类似地,目录可以指定对其中所有文件通用的局部变量值;参见 目录局部变量。尽管 Emacs 已采取措施防范这些变量被滥用,但仅因某个扩展包过于乐观地设置 safe-local-variable 就可能产生安全漏洞,这类问题十分常见。若要同时禁用文件和目录的该功能,可将 enable-local-variables 设置为 nil

访问控制

尽管 Emacs 通常遵循底层操作系统的访问权限,但在某些情况下会特殊处理访问行为。例如,文件名可以带有处理程序,对文件进行特殊处理并执行独立的访问检查。See 实现“魔法”文件名机制。此外,即使对应文件可写,缓冲区也可能是只读的,反之亦然,这会出现类似 ‘File passwd is write-protected; try to save anyway? (yes or no)’ 的提示信息。See 只读缓冲区

身份认证

Emacs 提供多个处理密码的函数,例如 read-passwd。See 读取密码。 尽管这些函数不会主动泄露密码,但其实现无法防范能够访问 Emacs 内部的蓄意攻击者。例如,即便 Elisp 代码使用 clear-string 在使用后清除内存中的密码,密码残留仍可能存在于垃圾回收的空闲链表中。See 修改字符串

代码注入

Emacs 可以向许多其他应用发送命令,应用应当确保作为这些命令操作数传入的字符串不会被误解析为指令。例如,使用 shell 命令将文件 a 重命名为 b 时,不要直接使用字符串 mv a b,因为任一文件名都可能以 ‘-’ 开头,或包含 ‘;’ 等 shell 元字符。尽管 shell-quote-argument 等函数有助于避免此类问题,但并非万能;例如在 POSIX 平台上,shell-quote-argument 会转义 shell 元字符,但不会处理开头的 ‘-’。在 MS-Windows 上,对 ‘%’ 的转义处理假定环境变量名中不包含 ‘^’。See Shell 参数。通常,使用 call-process 比子 shell 更安全。See 创建同步进程。而使用 Emacs 内置函数则更为安全;例如,使用 (rename-file "a" "b" t) 代替调用 mv。See 修改文件名与属性

编码系统

Emacs 会尝试推断所访问文件与网络连接的编码系统。See 编码系统。 若 Emacs 推断错误,或网络连接的另一方与 Emacs 的推断不一致,系统行为可能不可靠。此外,即使推断正确,Emacs 也常会使用其他程序无法处理的字节。例如,在 Emacs 中空字节只是一个普通字符,但许多其他应用将其视为字符串结束符,会错误处理包含空字节的字符串或文件。

环境与配置变量

POSIX 定义了多个会影响 Emacs 行为的环境变量。任何名称完全由大写 ASCII 字母、数字和下划线组成的环境变量,都可能影响 Emacs 的内部行为。Emacs 使用多个此类变量,例如 EMACSLOADPATH。See 库搜索。在部分平台上,某些环境变量(如 PATHPOSIXLY_CORRECTSHELLTMPDIR)需要配置正确的值,才能让 Emacs 调用的工具表现出标准行为。即使是 TZ 这类看似无害的变量也可能存在安全隐患。See 操作系统环境

Emacs 的自定义选项及其他变量也存在类似考量。例如,若变量 shell-file-name 指定了行为非标准的 shell,基于 Emacs 的应用可能出现异常。

安装

安装 Emacs 时,若安装目录层级可被不可信用户修改,则该应用不可被信任。这同样适用于 Emacs 所使用程序的目录层级,以及 Emacs 读写的文件所在目录层级。

网络访问

Emacs 常会访问网络,你可能希望配置它以避免其执行非必要的网络访问。例如,除非将 tramp-mode 设置为 nil,否则使用特定语法的文件名会被识别为网络文件,并通过网络获取。See The Tramp Manual in The Tramp Manual.

竞态条件

Emacs 应用与其他应用一样存在竞态条件问题。例如,即使 (file-readable-p "foo.txt") 返回 t,也可能因为其他程序在调用 file-readable-p 与当前时刻之间修改了文件权限,导致 foo.txt 实际不可读。See 测试文件可访问性

资源限制

当 Emacs 耗尽内存或其他操作系统资源时,其行为可靠性会下降,原本可以正常运行完成的计算可能中止并返回到顶层。这可能导致 Emacs 无法执行某些本应完成的操作。