SuperAPI AI 工具集

defense-in-depth validation

编程与开发

查看项目

更新于 10-15 07:56

技能介绍

Defense-in-Depth Validation(纵深防御式校验)是一种用于防止无效数据引发缺陷的工程实践。它的核心原则是:在数据流经的每一层都进行校验,让缺陷在结构上变得不可能发生。

用途

当修复一个由无效数据导致的缺陷时,只在某一处添加校验往往感觉已经足够。但这一处检查可能被不同的代码路径、重构或 mock 绕过。该方法的目标不是“修复了这个缺陷”,而是“让这个缺陷不可能发生”。不同层能捕获不同情况:入口校验捕获大多数缺陷,业务逻辑捕获边界情况,环境守卫防止特定上下文中的危险,调试日志在其它层失效时提供帮助。

四层校验

第一层:入口点校验

目的:在 API 边界拒绝明显无效的输入。

示例代码:

function createProject(name: string, workingDirectory: string) {
  if (!workingDirectory || workingDirectory.trim() === '') {
    throw new Error('workingDirectory cannot be empty');
  }
  if (!existsSync(workingDirectory)) {
    throw new Error(`workingDirectory does not exist: ${workingDirectory}`);
  }
  if (!statSync(workingDirectory).isDirectory()) {
    throw new Error(`workingDirectory is not a directory: ${workingDirectory}`);
  }
  // ... proceed
}

第二层:业务逻辑校验

目的:确保数据对当前操作是有意义的。

示例代码:

function initializeWorkspace(projectDir: string, sessionId: string) {
  if (!projectDir) {
    throw new Error('projectDir required for workspace initialization');
  }
  // ... proceed
}

第三层:环境守卫

目的:在特定上下文中阻止危险操作。

示例代码:

async function gitInit(directory: string) {
  // In tests, refuse git init outside temp directories
  if (process.env.NODE_ENV === 'test') {
    const normalized = normalize(resolve(directory));
    const tmpDir = normalize(resolve(tmpdir()));

    if (!normalized.startsWith(tmpDir)) {
      throw new Error(
        `Refusing git init outside temp dir during tests: ${directory}`
      );
    }
  }
  // ... proceed
}

第四层:调试插桩

目的:为事后取证捕获上下文。

示例代码:

async function gitInit(directory: string) {
  const stack = new Error().stack;
  logger.debug('About to git init', {
    directory,
    cwd: process.cwd(),
    stack,
  });
  // ... proceed
}

使用方式

当发现一个缺陷时,按以下步骤应用该模式:

  1. 追踪数据流——坏值从哪里产生?在哪里被使用?
  2. 映射所有检查点——列出数据经过的每一个点。
  3. 在每一层添加校验——入口、业务、环境、调试。
  4. 测试每一层——尝试绕过第一层,验证第二层能否捕获。

示例

资料中给出的会话示例:

缺陷:空的 projectDir 导致 git init 在源码目录中执行。

数据流:

  • 测试设置 → 空字符串
  • Project.create(name, '')
  • WorkspaceManager.createWorkspace('')
  • git init 在 process.cwd() 中运行

添加的四层:

  • 第一层:Project.create() 校验非空、存在、可写
  • 第二层:WorkspaceManager 校验 projectDir 非空
  • 第三层:WorktreeManager 在测试中拒绝在 tmpdir 之外执行 git init
  • 第四层:在 git init 前记录堆栈跟踪日志

结果:全部 1847 个测试通过,缺陷无法复现。

关键洞察

四层都是必要的。在测试过程中,每一层都捕获了其它层遗漏的缺陷:

  • 不同代码路径绕过了入口校验
  • mock 绕过了业务逻辑检查
  • 不同平台上的边界情况需要环境守卫
  • 调试日志识别出结构性误用

不要只停留在一个校验点。在每一层都添加检查。

适用场景与限制

该方法适用于需要处理外部输入、跨多个模块传递数据、或在测试与生产等不同环境中执行危险操作的软件系统。资料未提供关于性能开销、具体语言限制或平台兼容性的进一步说明。