defense-in-depth-validation — скилл для Claude Code: валидация
Скилл учит агента ставить проверки данных на всех слоях, чтобы баг стал структурно невозможным. Пригодится, когда невалидные данные ломают выполнение глубоко в коде.
npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a claude-codeЧто делает defense-in-depth-validation
Скилл описывает четыре слоя валидации: на входе в API, в бизнес-логике, в защите окружения и в отладочном логировании. Каждый слой ловит свой класс ошибок, поэтому один пропущенный путь в коде не открывает дыру. Агент получает готовые примеры на TypeScript и JavaScript и разбирает по ним конкретный баг.
Порядок работы такой: проследить поток данных от источника плохого значения до места использования, перечислить все точки, через которые данные проходят, добавить проверку в каждой и протестировать каждую попыткой обойти первую. В разборе из практики пустой projectDir приводил к запуску git init в исходниках проекта — четыре слоя закрыли этот путь.
Отдельный раздел про безопасность: проверка на краю через CDN или WAF, повторный вывод авторизации на сервере вместо доверия к userId из тела запроса и условие владения прямо в SQL-запросе. Скилл не подключает библиотек и не требует ключей — это текстовое руководство, которое агент читает при разборе ошибок. Ставить его стоит, если у вас уже были баги, которые всплывали только на одном пути исполнения.
Какие задачи решает
- закрыть баг от невалидных данных так, чтобы он не воспроизводился
- найти все точки, через которые проходят данные перед использованием
- не дать мокам и обходным путям проскочить проверку на входе
- запретить опасные операции вроде
git initвне временной папки в тестах - перепроверить владение объектом в SQL-запросе, а не доверять данным клиента
Примеры запросов агенту
- Разбери этот баг с пустым projectDir и добавь валидацию на каждом слое, через который проходят данные
- Проверь, что моки в тестах не обходят проверку на входе, и добавь защиту в бизнес-логике
- Добавь проверку владения в SQL-запрос, чтобы баг в обработчике не пускал чужие данные
Как установить defense-in-depth-validation
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a claude-code2Вручную: положить файлы
~/.claude/skills/defense-in-depth-validation/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/defense-in-depth-validation/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a codex2Вручную: положить файлы
.agents/skills/defense-in-depth-validation/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a cursor2Вручную: положить файлы
.cursor/skills/defense-in-depth-validation/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install secondsky/claude-skills defense-in-depth-validation2Вручную: положить файлы
.github/skills/defense-in-depth-validation/SKILL.md1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a gemini-cli2Командой платформы
gemini skills install https://github.com/secondsky/claude-skills --path plugins/defense-in-depth-validation/skills/defense-in-depth-validationВручную: положить файлы
.devin/skills/defense-in-depth-validation/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о defense-in-depth-validation
Как установить defense-in-depth-validation в Claude?
Выполните npx skills add secondsky/claude-skills --skill defense-in-depth-validation -a claude-code. Скилл окажется в ~/.claude/skills/defense-in-depth-validation/SKILL.md.
Что делает defense-in-depth-validation?
Описывает четыре слоя проверки данных: вход, бизнес-логика, защита окружения и отладочное логирование. Агент применяет их, когда невалидные данные ломают выполнение глубоко в коде.
Чем этот скилл отличается от обычной проверки на входе?
Одна проверка обходится другим путём в коде, рефакторингом или моком. Скилл требует проверок на всех слоях, чтобы баг стал структурно невозможным.
Исходный текст
SKILL.md · MIT
---
name: defense-in-depth-validation
description: Validate at every layer data passes through to make bugs impossible. Use when invalid data causes failures deep in execution, requiring validation at multiple system layers.
metadata:
version: "1.1.0"
license: MIT
---
# Defense-in-Depth Validation
## Overview
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.
## Why Multiple Layers
Single validation: "We fixed the bug"
Multiple layers: "We made the bug impossible"
Different layers catch different cases:
- Entry validation catches most bugs
- Business logic catches edge cases
- Environment guards prevent context-specific dangers
- Debug logging helps when other layers fail
## The Four Layers
### Layer 1: Entry Point Validation
**Purpose:** Reject obviously invalid input at API boundary
```typescript
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
}
```
### Layer 2: Business Logic Validation
**Purpose:** Ensure data makes sense for this operation
```typescript
function initializeWorkspace(projectDir: string, sessionId: string) {
if (!projectDir) {
throw new Error('projectDir required for workspace initialization');
}
// ... proceed
}
```
### Layer 3: Environment Guards
**Purpose:** Prevent dangerous operations in specific contexts
```typescript
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
}
```
### Layer 4: Debug Instrumentation
**Purpose:** Capture context for forensics
```typescript
async function gitInit(directory: string) {
const stack = new Error().stack;
logger.debug('About to git init', {
directory,
cwd: process.cwd(),
stack,
});
// ... proceed
}
```
## Applying the Pattern
When you find a bug:
1. **Trace the data flow** - Where does bad value originate? Where used?
2. **Map all checkpoints** - List every point data passes through
3. **Add validation at each layer** - Entry, business, environment, debug
4. **Test each layer** - Try to bypass layer 1, verify layer 2 catches it
## Example from Session
Bug: Empty `projectDir` caused `git init` in source code
**Data flow:**
1. Test setup → empty string
2. `Project.create(name, '')`
3. `WorkspaceManager.createWorkspace('')`
4. `git init` runs in `process.cwd()`
**Four layers added:**
- Layer 1: `Project.create()` validates not empty/exists/writable
- Layer 2: `WorkspaceManager` validates projectDir not empty
- Layer 3: `WorktreeManager` refuses git init outside tmpdir in tests
- Layer 4: Stack trace logging before git init
**Result:** All 1847 tests passed, bug impossible to reproduce
## Key Insight
All four layers were necessary. During testing, each layer caught bugs the others missed:
- Different code paths bypassed entry validation
- Mocks bypassed business logic checks
- Edge cases on different platforms needed environment guards
- Debug logging identified structural misuse
**Don't stop at one validation point.** Add checks at every layer.
## Security defense-in-depth
The same layered approach is the standard pattern for security controls: trust
is never granted at a single point, so that a bug or bypass in any one layer
cannot by itself compromise the system. Each request is checked independently
at the edge, in the handler, and at the data layer.
- **Layer 1 (edge)**: rate-limit and filter at the edge (CDN/WAF such as
Cloudflare or AWS WAF) so abusive traffic never reaches the origin.
- **Layer 2 (handler)**: re-derive authorization server-side from the session
— never trust a client-supplied claim like a `userId` in the body.
- **Layer 3 (data)**: enforce the ownership invariant in the database query so
that even a handler bug cannot cross tenant boundaries.
```javascript
// Layer 2 — re-derive authz server-side, never trust client claims
app.put('/docs/:id', async (req, res) => {
const user = await verifySession(req.cookies.session); // throws if invalid
// Layer 3 — DB clause re-checks ownership; a handler bug still can't cross tenants
const updated = await db.query(
'UPDATE docs SET title = $1 WHERE id = $2 AND owner_id = $3 RETURNING *',
[req.body.title, req.params.id, user.id]
);
if (!updated.rowCount) return res.status(403).send('Not allowed');
res.json(updated.rows[0]);
});
```
Defense in depth means no single layer's failure is sufficient to compromise
the system.
© secondsky · MIT · secondsky/claude-skills