Defense-in-Depth Validation by obra/superpowers-skills
npx skills add https://github.com/obra/superpowers-skills --skill 'Defense-in-Depth Validation'当你修复由无效数据引起的错误时,在一个地方添加验证似乎就足够了。但这一单一检查可能会被不同的代码路径、重构或模拟所绕过。
核心原则: 在数据传递的每一层都进行验证。从结构上杜绝错误发生的可能性。
单一验证:“我们修复了错误” 多层验证:“我们让错误不可能发生”
不同层级捕获不同的情况:
目的: 在 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
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
目的: 防止在特定上下文中执行危险操作
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
}
当你发现一个错误时:
错误:空的 projectDir 导致在源代码目录执行 git init
数据流:
Project.create(name, '')WorkspaceManager.createWorkspace('')git init 在 process.cwd() 中运行添加的四层防御:
Project.create() 验证非空/存在/可写WorkspaceManager 验证 projectDir 非空WorktreeManager 在测试中拒绝在 tmpdir 之外执行 git init结果: 所有 1847 个测试通过,错误无法复现
所有四层都是必要的。在测试过程中,每一层都捕获了其他层遗漏的错误:
不要止步于一个验证点。 在每一层都添加检查。
每周安装次数
–
代码仓库
GitHub 星标数
580
首次出现
–
安全审计
When you fix a bug caused by invalid data, adding validation at one place feels sufficient. But that single check can be bypassed by different code paths, refactoring, or mocks.
Core principle: Validate at EVERY layer data passes through. Make the bug structurally impossible.
Single validation: "We fixed the bug" Multiple layers: "We made the bug impossible"
Different layers catch different cases:
Purpose: Reject obviously invalid input at API boundary
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
}
Purpose: Ensure data makes sense for this operation
function initializeWorkspace(projectDir: string, sessionId: string) {
if (!projectDir) {
throw new Error('projectDir required for workspace initialization');
}
// ... proceed
}
Purpose: Prevent dangerous operations in specific contexts
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
}
Purpose: Capture context for forensics
async function gitInit(directory: string) {
const stack = new Error().stack;
logger.debug('About to git init', {
directory,
cwd: process.cwd(),
stack,
});
// ... proceed
}
When you find a bug:
Bug: Empty projectDir caused git init in source code
Data flow:
Project.create(name, '')WorkspaceManager.createWorkspace('')git init runs in process.cwd()Four layers added:
Project.create() validates not empty/exists/writableWorkspaceManager validates projectDir not emptyWorktreeManager refuses git init outside tmpdir in testsResult: All 1847 tests passed, bug impossible to reproduce
All four layers were necessary. During testing, each layer caught bugs the others missed:
Don't stop at one validation point. Add checks at every layer.
Weekly Installs
–
Repository
GitHub Stars
580
First Seen
–
Security Audits
Azure RBAC 权限管理工具:查找最小角色、创建自定义角色与自动化分配
117,000 周安装