在沙箱环境中,路径 ~/.local/bin/ 往往被视为可疑目标。然而,一个容易被忽视的技术细节是:当波浪号(tilde)出现在引号内时,它并不会自动扩展为当前用户的家目录。

Tilde 扩展的陷阱
许多开发者习惯在 ~/.bashrc 或 ~/.zshrc 中通过以下方式添加自定义二进制文件路径:
export PATH="$PATH:~/.local/bin/"
这种写法存在隐患。根据 Bash 官方文档,Tilde 扩展仅在未引用的输入中发生。具体而言,Bash 只在变量赋值语句中等号左侧、冒号后或第一个双等号后的未引用 Tilde 前缀执行扩展。在上述示例中,由于整个字符串被双引号包裹,~ 保持字面意义,最终导致系统尝试将名为 ./~/.local/bin/ 的相对路径加入环境变量。
安全隐患演示
攻击者可以利用这一机制,在当前工作目录下创建一个名为 ~ 的子目录,并在其中放置恶意二进制文件。以下实验展示了该漏洞的实际效果:
$ ls -la
total 0
drwxr-xr-x@ 2 dc staff 64 Oct 2 13:37 .
drwxr-x---+ 105 dc staff 3360 Oct 2 13:37 ..
$ mkdir -p ./~/.local/bin/
$ printf '#include <stdio.h>\nint main() { puts("hello"); }'>a.c; gcc a.c -o ./~/.local/bin/kek
$ PATH="~/.local/bin/" kek
hello
$ tree -f
.
├── ./~
│ └── ./~/.local
│ └── ./~/.local/bin
│ └── ./~/.local/bin/kek
└── ./a.c
4 directories, 2 files
如上所示,命令 kek 被执行时,系统从当前目录下的 ./~/.local/bin/ 找到了二进制文件,而非用户真正的家目录。这意味着任何拥有当前目录写入权限的沙箱进程都可能劫持后续的命令执行。
正确配置与检查方法
虽然在不使用引号的场景下(如 export PATH=$PATH:~/.local/bin),Bash 和 Zsh 确实会在变量赋值过程中执行 Tilde 扩展,但这种依赖非常脆弱。例如,配置文件中若出现多余的空格,可能导致解析失败或行为异常。
最稳健的解决方案是显式使用 $HOME 环境变量替代波浪号:
export PATH="$PATH:$HOME/.local/bin/"
用户可以快速检查当前环境是否存在此类配置错误:
$ echo "$PATH" | grep -- '~'
或者逐行查看 PATH 中的条目:
$ echo "$PATH" | tr ':' '\n' | grep '~'
~/.local/bin/
如果上述命令返回了包含波浪号的路径条目,建议立即修改 .bashrc、.zshrc 或 .profile 文件,将所有硬编码的 ~ 替换为 $HOME。





