defense-in-depth-validation by secondsky/claude-skills
npx skills add https://github.com/secondsky/claude-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 个测试通过,错误无法复现
所有四层都是必要的。在测试过程中,每一层都捕获了其他层遗漏的错误:
不要止步于一个验证点。 在每一层都添加检查。
每周安装次数
76
代码仓库
GitHub 星标数
93
首次出现
2026年1月25日
安全审计
安装于
gemini-cli63
claude-code63
codex62
opencode61
cursor60
github-copilot59
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
76
Repository
GitHub Stars
93
First Seen
Jan 25, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli63
claude-code63
codex62
opencode61
cursor60
github-copilot59
Azure PostgreSQL 无密码身份验证配置指南:Entra ID 迁移与访问管理
34,800 周安装