Defense-in-Depth Validation 是一种面向数据校验的工程实践模式,核心目标是当无效数据在深层执行中引发失败时,通过在数据流经的每一层都加入校验,使这类缺陷在结构上无法发生。
用途
当修复一个由无效数据引起的缺陷时,只在单一位置添加校验往往感觉已经足够。但资料指出,这种单一检查可能被不同的代码路径、重构或 mock 绕过。因此该模式主张:在数据经过的每一层都进行校验,让缺陷在结构上变得不可能。
核心理念
单一校验对应的是“我们修复了这个缺陷”;多层校验对应的是“我们让这个缺陷不可能发生”。不同层能捕获不同情况:入口校验捕获大多数缺陷,业务逻辑捕获边界情况,环境守卫阻止特定上下文中的危险,调试日志在其他层失效时提供帮助。
四层结构
第一层:入口点校验。目的是在 API 边界拒绝明显无效的输入。资料给出的示例是 createProject 函数,它检查 workingDirectory 是否为空、是否存在、是否为目录,不满足则抛出错误。
第二层:业务逻辑校验。目的是确保数据对当前操作有意义。示例是 initializeWorkspace 函数,检查 projectDir 是否提供,否则抛出错误。
第三层:环境守卫。目的是在特定上下文中阻止危险操作。示例是 gitInit 函数,在测试环境(NODE_ENV 为 test)下,若目录不在临时目录内则拒绝执行 git init。
第四层:调试插桩。目的是为事后取证捕获上下文。示例是在 git init 之前记录目录、当前工作目录和调用栈。
应用方式
资料给出的应用步骤为:发现缺陷时,先追踪数据流,确定坏值从何而来、在何处被使用;再映射所有检查点,列出数据经过的每一个点;然后在每一层添加校验,包括入口、业务、环境和调试;最后测试每一层,尝试绕过第一层并验证第二层能否捕获。
案例
资料描述了一个会话中的真实案例:缺陷是空的 projectDir 导致在源码目录执行 git init。数据流为:测试设置产生空字符串,经过 Project.create(name, '')、WorkspaceManager.createWorkspace(''),最终 git init 在 process.cwd() 中运行。随后添加了四层校验:Project.create() 校验非空、存在、可写;WorkspaceManager 校验 projectDir 非空;WorktreeManager 在测试中拒绝在临时目录之外执行 git init;git init 前记录调用栈。结果是 1847 个测试全部通过,缺陷无法复现。
关键洞察
资料强调四层都是必要的。测试期间每一层都捕获了其他层遗漏的缺陷:不同代码路径绕过了入口校验,mock 绕过了业务逻辑检查,不同平台上的边界情况需要环境守卫,调试日志识别出结构性误用。结论是不要只停留在一个校验点,而应在每一层都添加检查。
限制
资料未提供该模式的具体安装方式、依赖要求、支持平台或性能开销等信息,暂未提供。