MATLAB

路径搜索顺序:当前文件夹优先于搜索路径,同名脚本注意谁被运行

👤 为我痴狂 👁 4 阅读 ❤ 0 点赞 ➦ 0 分享 📅 2026-10-12
首页› 理学› MATLAB› 正文
路径搜索顺序:当前文件夹优先于搜索路径,同名脚本注意谁被运行

从一次「脚本被静默替换」的故障出发,解剖 PATH / sys.path / CLASSPATH / node_modules 的查找机制与防御性工程实践

摘要

同名脚本被错误执行,是运维与开发中最难排查的一类故障:命令敲下去没有报错,行为却完全不对。本文以「当前文件夹优先于搜索路径」这一被广泛忽视的默认规则为主线,横向对比 Shell、Python、Java、Node.js、Windows CMD/PowerShell、动态链接器 ld.so 等主流运行时的路径查找顺序,剖析其背后的设计权衡与安全代价,并给出可复现的验证脚本、可落地的工程规范与前沿防御思路。

全文围绕一条独创性分析主线展开:「隐式当前目录优先」是历史兼容性的产物,而非安全默认值;现代工程应当把「谁被运行」从运行时猜测,转变为构建期与部署期的显式契约。

一、问题的起点:一次「脚本被静默替换」的故障复盘

先还原一个在真实工程中反复出现的场景。某团队在部署机上执行一个名为 deploy.sh 的发布脚本,脚本内容、权限、路径都没有变化,但某天开始,执行结果变成了「什么都没做,直接退出 0」。排查数小时后发现:运维同学在同一个目录下新建了一个用于本地调试的 deploy.sh,而调用方使用的是相对路径 ./deploy.sh 与 deploy.sh 混用,最终命中的是那个「空壳」脚本。

这个故障的关键不在于「写错了脚本」,而在于「谁被运行」这件事从未被显式声明。系统按一套隐式规则替我们做了选择,而我们对这套规则的理解往往停留在「大概就是找得到就运行」的模糊层面。一旦目录结构、工作目录(CWD)、环境变量发生微小变化,被选中的目标就可能悄然切换。

本文评述:这类故障之所以「静默」,是因为路径查找本身是一个成功即沉默的过程——找到就执行,找不到才报错。它不会告诉你「我本来可能找到另一个」。因此,理解路径搜索顺序,本质上是在理解一个默认优先级契约,而不是在记一条命令的用法。

本文的主线由此确立:路径搜索顺序是运行时替开发者做出的隐式决策,而现代工程的核心任务,是把这些隐式决策显式化、可验证化。下面我们将沿着这条主线,逐一解剖主流运行时的查找机制。

二、路径搜索的本质:查找顺序即优先级契约

2.1 搜索路径是一个有序列表,不是一个集合

几乎所有运行时的路径查找都可以抽象为同一个模型:给定一个「名字」(命令名、模块名、类名、库名),在一串有序的目录列表中依次查找,返回第一个命中项。这个「有序」是全部问题的根源——顺序决定了优先级,优先级决定了谁被运行。

用伪代码表达,这个模型极其简单:

function resolve(name, search_path):
    for dir in search_path:          # 顺序敏感
        candidate = join(dir, name)
        if exists(candidate) and is_executable(candidate):
            return candidate         # 第一个命中即返回
    raise NotFound(name)

本文评述:这个模型的价值在于,它把「同名脚本谁被运行」还原为一个纯粹的列表顺序问题。只要我们能拿到某个运行时真实的 search_path 列表,就能确定性地预测结果;反之,任何对 search_path 的隐式修改(追加当前目录、插入空字符串、继承父进程环境)都会改变优先级契约。

2.2 空字符串与「当前目录」的等价陷阱

在 POSIX 传统中,PATH 里的空字符串(例如 PATH=/usr/bin::/bin 中间那个空段)表示当前目录。这与显式写 . 在语义上等价,但更隐蔽——因为肉眼很难发现「两个冒号之间什么都没有」。很多「当前目录优先」的意外,正是由这种不可见字符造成的。

PATH 写法 是否含当前目录 可读性 风险等级
/usr/bin:/bin 否 高 低
.:/usr/bin:/bin 是(显式) 高 中
/usr/bin::/bin 是(隐式空段) 低 高
/usr/bin:/bin:. 是(末尾) 高 中

表中风险等级的判断依据是:当前目录是否可能被不可信内容写入。在共享目录、临时目录、下载目录中执行命令时,当前目录优先意味着「目录里的任何文件都可能劫持你的命令」。

三、Shell 世界:PATH 与「当前目录」的百年纠葛

3.1 现代 Shell 默认不搜索当前目录

一个常被误解的事实是:在主流 Linux 发行版的默认配置中,bash、zsh、dash 并不会把当前目录加入 PATH。也就是说,执行 deploy.sh 会报 command not found,必须写 ./deploy.sh。这是 2000 年代之后各大发行版逐步收紧的默认策略,目的是防止「下载一个目录,cd 进去,随手敲个 ls 就中招」。

但这里有一个关键区分:「不搜索当前目录」不等于「当前目录不影响执行」。当你显式写 ./deploy.sh 时,你其实是在用相对路径直接指定文件,Shell 不再查 PATH,而是把 ./deploy.sh 交给内核 execve。此时「谁被运行」由路径字面量决定,反而更可控。

笔者认为:Shell 层的「当前目录优先」问题,本质上是相对路径与 PATH 查找的语义混淆。很多人以为 deploy.sh 和 ./deploy.sh 只是「少写两个字符」,实际上前者走 PATH 查找、后者走相对路径解析,是两条完全不同的代码路径。

3.2 哪些场景会重新引入当前目录

尽管默认安全,但以下场景会把当前目录重新拉回搜索路径,需要特别警惕:

  • PATH 中残留空段或 .:常见于从旧系统迁移的配置、手工拼接的 PATH、某些 SDK 的初始化脚本。
  • source / . 加载脚本:source deploy.sh 直接在当前 Shell 环境中执行,不涉及 PATH,但会继承当前目录的语义。
  • cron 与 systemd 的默认 PATH:cron 的默认 PATH 通常很短,某些发行版历史上包含当前目录;systemd 服务则默认使用固定的 PATH,需要显式配置。
  • Windows CMD 的隐式当前目录:CMD 默认会先搜索当前目录,这是与 POSIX 最大的差异之一(详见第六节)。

3.3 验证与加固:三条命令看清真相

# 1. 查看 PATH 的每一段,空段会显示为空行
echo "$PATH" | tr ':' '\n' | cat -A

# 2. 查看某个命令最终解析到哪个文件
type -a deploy.sh        # bash/zsh
command -v deploy.sh     # POSIX 兼容

# 3. 查看所有同名命令的完整列表(谁在前谁优先)
which -a python3

本文评述:type -a 与 which -a 是排查同名脚本问题的第一工具。它们把「隐式优先级」变成「可见列表」,这正是本文主线所强调的「显式化」在 Shell 层的最小实践。

四、Python:sys.path[0] 的隐式当前目录与 -P 开关

4.1 脚本模式下,脚本所在目录被自动插入 sys.path[0]

Python 的模块查找由 sys.path 决定。在直接运行脚本(python script.py)时,Python 会把脚本所在目录插入到 sys.path 的最前面。注意:是「脚本所在目录」,不是「当前工作目录」——这两者在 python /path/to/script.py 时并不相同。

这个设计的历史动机是让脚本能方便地 import 同目录下的兄弟模块。但它带来的副作用是:如果脚本所在目录里存在一个与标准库或第三方库同名的文件(例如 json.py、random.py、logging.py),它就会遮蔽(shadow)真正的库,导致难以理解的导入错误。

运行方式 sys.path[0] 风险点
python script.py script.py 所在目录 同目录同名文件遮蔽标准库
python -m module 当前工作目录 CWD 中同名包遮蔽已安装包
python -c "..." 空字符串(即 CWD) CWD 内容影响导入
python -P script.py 不插入脚本目录 推荐用于不可信目录

4.2 -P 开关与 PYTHONSAFEPATH:官方给出的答案

Python 3.11 引入了 -P 命令行开关和对应的环境变量 PYTHONSAFEPATH,用于禁止把脚本目录或 CWD 插入 sys.path。这是 CPython 官方对「隐式当前目录优先」这一历史包袱的正面回应。

# 查看 sys.path 的真实内容
python3 -c "import sys; [print(repr(p)) for p in sys.path]"

# 启用安全路径模式
python3 -P script.py
PYTHONSAFEPATH=1 python3 script.py

# 观察模块实际来源
python3 -c "import json; print(json.__file__)"

本文评述:-P 的意义不仅是「多一个开关」,而是官方在语言层面承认了「隐式当前目录优先」是一个需要被显式关闭的风险默认值。这与本文主线完全一致:安全的路径行为应当是可选的显式配置,而不是默认的隐式行为。

4.3 虚拟环境与 pip 的路径叠加

虚拟环境(venv)通过修改 sys.prefix 和 site-packages 路径来隔离依赖,但它并不改变 sys.path[0] 的插入规则。也就是说,即使激活了 venv,脚本目录仍然会被优先插入。这意味着「venv 隔离」并不能防御同目录同名文件的遮蔽问题。实践中,很多「明明装了包却 import 到别的版本」的问题,根源都在这里。

五、Java 与 Node.js:CLASSPATH 与 node_modules 的向上查找

5.1 Java:CLASSPATH 中的当前目录与 -cp 覆盖

Java 的类查找由 ClassLoader 和 CLASSPATH 共同决定。历史上,如果未显式设置 CLASSPATH,默认值包含当前目录(.)。这意味着在项目根目录下执行 java Main 时,当前目录下的 .class 文件会被优先加载。

现代实践强烈建议用 -cp / -classpath 显式指定,或用构建工具(Maven、Gradle)生成的 classpath 文件,避免依赖隐式默认值。Java 9 引入模块系统后,类加载的可见性进一步收紧,但「同名类被谁加载」的问题在复杂依赖树中依然存在——这正是「JAR Hell」的根源之一。

机制 查找顺序 同名冲突表现
Bootstrap ClassLoader JDK 核心类优先 无法被应用覆盖
Extension / Platform 扩展目录 少见冲突
Application ClassLoader -cp 顺序,先到先得 JAR Hell 主战场

5.2 Node.js:node_modules 的逐级向上查找

Node.js 的模块解析规则(CommonJS)是「从当前文件所在目录开始,逐级向上查找 node_modules」。这个设计让每个包都能拥有自己的依赖副本,但也带来了两个经典问题:

  • 幽灵依赖(Phantom Dependency):因为向上查找,代码可以 require 到并未在自身 package.json 中声明的包,只是恰好被上层某个依赖装了。
  • 同名包多版本共存:不同层级的 node_modules 可能装着不同版本的同一个包,require 结果取决于调用位置。

ESM 的解析规则更严格,要求显式扩展名,并区分 bare specifier 与相对路径,但「向上查找 node_modules」的核心逻辑保持一致。pnpm 通过符号链接 + 内容寻址存储,从结构上消除了幽灵依赖;Yarn PnP 则干脆取消了 node_modules,用 .pnp.cjs 显式记录每个包的解析结果。

本文评述:pnpm 与 Yarn PnP 的共同思路,是把「运行时向上查找」变成「构建期显式解析」。这与本文主线高度吻合——路径解析的可预测性,应当由构建工具在安装阶段锁定,而不是留给运行时逐级试探。

六、Windows 与动态链接器:另一套「当前目录优先」的家族

6.1 Windows CMD 与 PowerShell 的差异

Windows CMD 的命令查找顺序历史上是:当前目录 → PATH 目录。这与 POSIX 默认行为相反,是 Windows 上「同名脚本被劫持」问题更突出的原因。PowerShell 则默认不搜索当前目录,需要显式写 .\script.ps1,这一点与 POSIX Shell 更接近。

环境 是否默认搜索当前目录 推荐写法
Linux bash/zsh 否 ./script.sh
Windows CMD 是(历史默认) .\script.bat 或全路径
PowerShell 否 .\script.ps1
Windows 可执行文件加载 是(DLL 搜索) 全路径或 SetDllDirectory

6.2 动态链接器 ld.so 与 LD_LIBRARY_PATH

Linux 下动态库的查找由 ld.so 负责,其顺序大致为:DT_RPATH → LD_LIBRARY_PATH → DT_RUNPATH → ld.so.cache → 默认目录(/lib、/usr/lib 等)。历史上,如果可执行文件没有设置 DT_RPATH,且环境变量中未指定,某些配置会回退到当前目录——这正是「DLL 劫持 / so 劫持」类漏洞的温床。

现代发行版普遍通过 -Wl,-z,origin、$ORIGIN、RPATH 加固、以及 noexec 挂载等手段收紧。但 LD_LIBRARY_PATH 一旦被污染,仍然可以劫持整个进程的库加载。

# 查看一个可执行文件依赖的库及其解析路径
ldd /usr/bin/ls

# 查看动态段中的 RPATH / RUNPATH
readelf -d /usr/bin/ls | grep -E 'RPATH|RUNPATH'

# 临时指定库搜索路径(谨慎使用)
LD_LIBRARY_PATH=/opt/mylib ./myapp

本文评述:动态链接器的路径问题比脚本层更危险,因为它是进程级的、对用户不可见的。用户敲下命令时看到的是程序名,但实际加载的库可能来自完全不同的目录。这也是为什么「供应链安全」必须把二进制加载路径纳入审计范围。

七、安全视角:路径劫持、CWE 分类与真实案例

7.1 CWE 中的相关条目

路径搜索顺序问题在通用缺陷枚举(CWE)中有明确对应。CWE-426(Untrusted Search Path)描述的是「程序使用不可信来源的搜索路径」,CWE-427(Uncontrolled Search Path Element)则聚焦「搜索路径中的某个元素可被外部控制」。两者经常同时出现,构成路径劫持类漏洞的核心。

CWE 编号 名称 典型场景
CWE-426 Untrusted Search Path PATH 含当前目录
CWE-427 Uncontrolled Search Path Element 可写目录在 PATH 中
CWE-428 Unquoted Search Path Windows 服务路径未加引号

7.2 攻击模型:为什么「当前目录优先」是放大器

假设攻击者能向某个目录写入文件,而受害者的 PATH 或库搜索路径包含该目录。攻击者只需放一个与常用命令同名的可执行文件,等待受害者在该目录下执行命令,即可获得代码执行。这个模型的关键在于:攻击者不需要修改任何系统文件,只需要「恰好命名正确」。

在共享主机、CI 构建目录、临时解压目录等场景中,这种「可写目录 + 路径优先」的组合非常常见。这也是为什么安全基线普遍要求:PATH 中不得包含当前目录、不得包含任何普通用户可写的目录。

笔者认为:路径劫持的可怕之处在于它的低成本与高隐蔽。攻击者不需要漏洞利用链,只需要一个文件名。防御的核心不是「检测恶意文件」,而是「消除隐式优先级」——让运行时不再有机会在错误的目录里找到东西。

7.3 供应链视角:构建环境中的路径污染

现代软件供应链把路径问题放大到了新的量级。CI/CD 流水线中,构建脚本、依赖安装、测试执行往往在同一个工作目录下连续进行。如果某个依赖的安装脚本(如 npm 的 postinstall)向当前目录写入了与后续命令同名的文件,就可能影响后续步骤的执行结果。这类风险在「依赖即代码」的模型下,已经从「本地问题」升级为「供应链问题」。

SLSA(Supply-chain Levels for Software Artifacts)等框架强调构建过程的隔离与可验证,其思路与本文主线一致:把「谁被运行」从环境猜测,变成构建清单中的显式记录。

八、可复现验证:一套跨语言的排查方法论

8.1 通用排查四步法

面对「同名脚本谁被运行」的问题,可以按以下四步系统排查,适用于绝大多数运行时:

  1. 确认名字:明确你要运行的确切名字(命令名、模块名、类名、库名)。
  2. 导出搜索路径:用运行时提供的工具打印完整的有序搜索列表。
  3. 逐项检查命中:按顺序检查每个目录中是否存在同名项,第一个命中即答案。
  4. 固化契约:用绝对路径、显式 classpath、锁定文件等方式,把结果固定下来。

8.2 各语言的最小验证脚本

# Shell:列出所有同名命令的解析结果
type -a python3
which -a python3

# Python:打印 sys.path 与模块来源
python3 -c "import sys; print('\n'.join(sys.path))"
python3 -c "import os; print(os.__file__)"

# Java:打印 classpath 与类来源
java -XshowSettings:properties -version 2>&1 | grep java.class.path
java -verbose:class Main 2>&1 | grep 'Main'

# Node.js:打印模块解析路径
node -e "console.log(require.resolve('lodash'))"
node -e "console.log(module.paths)"

本文评述:这些命令的共同价值,是把「运行时内部的有序列表」暴露给开发者。一旦列表可见,同名冲突就从「玄学」变成了「排序问题」,排查成本大幅下降。

8.3 一个可复现的最小实验

下面这个实验可以在任何 Linux 环境中复现,用于直观感受「当前目录优先」的影响(模拟数据,仅用于演示机制):

mkdir -p /tmp/pathdemo && cd /tmp/pathdemo
printf '#!/bin/sh\necho "I am the LOCAL script"\n' > demo.sh
chmod +x demo.sh

# 情况一:当前目录不在 PATH 中
PATH=/usr/bin:/bin
demo.sh            # command not found
./demo.sh          # 输出 I am the LOCAL script

# 情况二:把当前目录加入 PATH
PATH=.:/usr/bin:/bin
demo.sh            # 输出 I am the LOCAL script(被本地脚本劫持)

这个实验说明:同一个命令名,在不同 PATH 配置下会解析到完全不同的文件。工程上要做的,就是让这个解析结果在任何环境下都保持一致。

九、工程实践:把「谁被运行」变成显式契约

9.1 脚本层:绝对路径与显式调用

  • 在自动化脚本中,统一使用绝对路径调用外部命令,或在脚本开头固定 PATH。
  • 避免在 PATH 中出现 . 或空段;用 echo "$PATH" | tr ':' '\n' | cat -A 定期检查。
  • 对关键脚本使用 #!/usr/bin/env bash 之外,还可考虑固定解释器绝对路径以降低不确定性。
#!/bin/bash
set -euo pipefail
# 固定 PATH,消除继承带来的不确定性
export PATH=/usr/local/bin:/usr/bin:/bin
# 使用绝对路径调用关键命令
/usr/bin/python3 /opt/app/main.py

9.2 Python 层:-P、显式包结构与入口点

  • 对不可信目录中的脚本,使用 python -P 或 PYTHONSAFEPATH=1。
  • 用 python -m package.module 替代直接运行脚本,配合正确的包结构,减少 sys.path[0] 的副作用。
  • 通过 console_scripts 入口点安装命令行工具,让解析由安装器负责,而非运行时猜测。

9.3 Java / Node 层:锁定依赖解析结果

  • Java:使用构建工具生成 classpath 文件,避免依赖环境变量 CLASSPATH;对关键服务使用模块化或分层类加载。
  • Node.js:使用 pnpm 或 Yarn PnP 消除幽灵依赖;提交 lockfile 并启用 --frozen-lockfile。
  • 容器化:在镜像构建阶段固定所有路径,运行时不再依赖宿主机环境。

9.4 组织层:把路径规范写进基线

技术手段之外,更重要的是把「路径安全」纳入团队规范与 CI 检查。例如:在 CI 中加入 PATH 审计步骤、禁止在共享目录中执行未固定路径的脚本、对生产环境的 systemd 服务显式声明 Environment=PATH=...。这些措施的共同目标,是让「谁被运行」在任何环境下都可预测、可审计。

层级 关键动作 验证方式
脚本 固定 PATH、绝对路径 type -a / which -a
Python -P、包结构、入口点 sys.path 打印
Java 显式 classpath -verbose:class
Node pnpm / PnP / lockfile require.resolve
容器 构建期固定路径 镜像层审计

十、前沿预判:从运行时猜测到供应链可验证

10.1 语言层面的「安全默认值」趋势

Python 的 -P、Node 的 PnP、Rust 的 Cargo 锁定、Go 的 module proxy 与 checksum 校验,都指向同一个方向:把「依赖从哪来」变成构建期可验证的事实,而不是运行时逐级查找的结果。这一趋势在未来几年会继续强化,路径搜索顺序的「隐式性」将被逐步压缩。

10.2 可验证构建与 SBOM

SBOM(软件物料清单)与可验证构建(Reproducible Builds)的普及,让「最终产物由哪些输入构成」变得可追溯。当路径解析结果被记录进构建清单,任何「运行时被替换」的行为都会在验证阶段暴露。本文评述:这是从「事后排查同名脚本」到「事前锁定解析结果」的范式转变,也是本文主线在供应链层面的自然延伸。

10.3 容器与沙箱:用隔离替代信任

容器、gVisor、Firecracker 等隔离技术,从另一个角度缓解了路径劫持问题:即使当前目录被写入恶意文件,其影响也被限制在沙箱内。但隔离不是万能药——如果沙箱内的 PATH 仍然包含可写目录,问题只是被推迟而非消除。真正的解法仍然是「显式契约 + 最小权限 + 可验证构建」的组合。

十一、结语

回到开头那次故障:如果调用方从一开始就使用绝对路径,或者部署脚本在开头固定了 PATH,那么「同名脚本被静默替换」根本不会发生。路径搜索顺序问题的本质,是把决策权交给了运行时,却没有把决策结果告诉任何人。

本文的主线可以浓缩为一句话:「谁被运行」应当是显式的、可验证的、可审计的契约,而不是运行时逐级试探的副产品。无论你写的是 Shell、Python、Java 还是 Node.js,这条原则都适用。理解路径搜索顺序,不是为了记住每个运行时的细节,而是为了在任何环境下都能确定性地回答那个最基础的问题——我敲下的这个名字,到底运行了什么。

参考文献

[1] Python Software Foundation. Python 3.11 Release Notes: -P and PYTHONSAFEPATH. 2022.

[2] Python Software Foundation. The Python Tutorial: Modules and sys.path. 2024.

[3] IEEE / MITRE. CWE-426: Untrusted Search Path. Common Weakness Enumeration, 2024.

[4] IEEE / MITRE. CWE-427: Uncontrolled Search Path Element. Common Weakness Enumeration, 2024.

[5] Node.js Foundation. Node.js Modules: Loading from node_modules Folders. 2024.

[6] pnpm Contributors. pnpm: Strict and Efficient Package Manager. 2024.

[7] Yarn Contributors. Yarn Plug'n'Play Specification. 2024.

[8] OpenSSF. SLSA: Supply-chain Levels for Software Artifacts v1.0. 2023.

[9] ld.so(8) man page. Linux Programmer's Manual: Dynamic Linker. 2024.

[10] Microsoft. Windows Command-Line Search Path Documentation. 2024.

[11] Oracle. Java Platform, Standard Edition: Setting the Class Path. 2024.

[12] GNU Bash Reference Manual. Command Search and Execution. 2024.

[13] OWASP Foundation. OWASP Top 10: A06 Vulnerable and Outdated Components. 2021.

[14] NIST. SP 800-218: Secure Software Development Framework. 2022.

[15] Reproducible Builds Project. Definitions and Documentation. 2024.

[16] SPDX Contributors. SPDX Specification v2.3. 2022.

[17] CycloneDX. Software Bill of Materials Specification v1.5. 2023.

[18] gVisor Authors. gVisor: Application Kernel for Containers. 2024.

[19] Firecracker Authors. Firecracker: Lightweight Virtualization for Serverless. 2020.

[20] Docker Inc. Dockerfile Reference: ENV and PATH. 2024.

[21] systemd Authors. systemd.exec: Environment and PATH. 2024.

[22] cron(8) man page. Linux Programmer's Manual: cron daemon. 2024.

[23] POSIX.1-2017. Standard for Information Technology: Shell Command Language. IEEE, 2017.

[24] Kerrisk, M. The Linux Programming Interface. No Starch Press, 2010.

[25] Robbins, A. Unix in a Nutshell. O'Reilly Media, 2005.

[26] Beazley, D. Python Distilled. Addison-Wesley, 2021.

[27] Ramalho, L. Fluent Python (2nd ed.). O'Reilly Media, 2022.

[28] Bloch, J. Effective Java (3rd ed.). Addison-Wesley, 2018.

[29] Osmani, A. Learning JavaScript Design Patterns. O'Reilly Media, 2012.

[30] Simpson, K. You Don't Know JS Yet: Scope & Closures. Independently Published, 2020.

[31] Python Packaging Authority. Entry Points Specification. 2024.

[32] Python Packaging Authority. Installing Packages: Virtual Environments. 2024.

[33] Maven Project. Maven: Classpath and Dependency Resolution. 2024.

[34] Gradle Inc. Gradle: Dependency Management. 2024.

[35] npm Inc. npm: package.json and node_modules Resolution. 2024.

[36] ECMAScript. ECMA-262: Modules. 2024.

[37] Microsoft. Dynamic-Link Library Search Order. 2024.

[38] Microsoft. PowerShell: about_Command_Precedence. 2024.

[39] Apple Inc. dyld: Dynamic Linker Man Page. 2024.

[40] FreeBSD Project. rtld(1): Run-Time Link-Editor. 2024.

[41] glibc Authors. ld.so: Dynamic Linker and Loader. 2024.

[42] OpenBSD Project. Security: PATH and Privilege Separation. 2024.

[43] Debian Project. Debian Policy Manual: PATH and File System. 2024.

[44] Red Hat. RHEL Security Guide: PATH and Environment. 2024.

[45] CIS Benchmarks. CIS Linux Benchmark: PATH Configuration. 2024.

[46] SANS Institute. Securing the Search Path. 2023.

[47] Trail of Bits. Path Hijacking in CI/CD Pipelines. 2023.

[48] GitHub Security Lab. Untrusted Search Path in Build Systems. 2023.

[49] Google. Building Secure and Reliable Systems. O'Reilly Media, 2020.

[50] Humble, J., Farley, D. Continuous Delivery. Addison-Wesley, 2010.

[51] Forsgren, N., Humble, J., Kim, G. Accelerate. IT Revolution Press, 2018.

[52] Morris, K. Infrastructure as Code (2nd ed.). O'Reilly Media, 2020.

[53] Burns, B., Beda, J., Hightower, K. Kubernetes: Up and Running. O'Reilly Media, 2022.

[54] Rice, L. Container Security. O'Reilly Media, 2020.

[55] Aumasson, J. Serious Cryptography (2nd ed.). No Starch Press, 2024.

[56] Anderson, R. Security Engineering (3rd ed.). Wiley, 2020.

[57] Saltzer, J., Schroeder, M. The Protection of Information in Computer Systems. Proceedings of the IEEE, 1975.

[58] Thompson, K. Reflections on Trusting Trust. Communications of the ACM, 1984.

[59] Wheeler, D. Fully Countering Trusting Trust through Diverse Double-Compiling. 2009.

[60] Lamb, C., Zacchiroli, S. Reproducible Builds: Increasing the Integrity of Software Supply Chains. IEEE Software, 2022.

[61] Ohm, M., et al. Backstabber's Knife Collection: A Review of Open Source Software Supply Chain Attacks. DIMVA, 2020.

声明:本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。

内容仅供学习参考。如需引用,请以原始文献为准。  全文约 12600 字 | 参考文献 61 篇(主要)。

🔒 复制本站文章内容需登录并达到 L3。当前:未登录

分享到

💬
微信
📷
朋友圈
🐧
QQ好友
🌐
QQ空间
👁
微博
📌
钉钉
🔗
复制链接
📑
复制图文

微信扫一扫分享

打开微信「扫一扫」,扫描二维码后在微信中分享给好友或朋友圈。

💬 评论 (0)

评论功能已关闭

⏸️ 本站暂未开放评论功能,不能进行评论,此为规划的后续开发预留
首页| 关于本网| 网站声明| 联系我们| 网站纠错| 服务| 网站地图
黔ICP备19010680号-1  |  邮箱:six528528@163.com
贵公网安备 52010302001819号
Copyright 2019-2026 http://www.databrush.com/ All rights reserved.
QQ
QQ扫一扫
Logo
DBN数据刷