mirror of
https://github.com/duthaho/claudekit.git
synced 2026-07-28 07:31:00 +03:00
301 lines
7.4 KiB
Markdown
301 lines
7.4 KiB
Markdown
---
|
|
name: defense-in-depth
|
|
user-invocable: false
|
|
description: >
|
|
Use when fixing any data-related bug, when building validation for critical data paths, or when a single validation point has already failed in production. Also activate whenever you hear "it slipped through," "the check was bypassed," or "it worked in tests but not production." Apply aggressively to any scenario involving data integrity, input validation across layers, or preventing bug recurrence through structural guarantees rather than single-point fixes.
|
|
---
|
|
|
|
# Defense-in-Depth
|
|
|
|
## When to Use
|
|
|
|
- After fixing any data-related bug
|
|
- Protecting critical data paths
|
|
- Preventing bug recurrence
|
|
- Building robust systems
|
|
- When single validation points have failed
|
|
|
|
## When NOT to Use
|
|
|
|
- Greenfield prototyping where speed matters more than robustness and requirements are still fluid
|
|
- Non-data-related bugs such as logic errors, race conditions, or algorithmic mistakes
|
|
- UI styling issues where visual correctness is the concern, not data integrity
|
|
|
|
---
|
|
|
|
## Core Concept
|
|
|
|
**"Validate at EVERY layer data passes through. Make the bug structurally impossible."**
|
|
|
|
Single validation points can be bypassed:
|
|
- Alternative code paths skip validation
|
|
- Refactoring accidentally removes checks
|
|
- Tests mock away the validation
|
|
|
|
Multiple layers create redundancy:
|
|
- Different layers catch different cases
|
|
- If one check fails, another catches it
|
|
- Bug becomes impossible, not just unlikely
|
|
|
|
---
|
|
|
|
## The Four-Layer Approach
|
|
|
|
### Layer 1: Entry Point Validation
|
|
|
|
Reject invalid input at API/system boundaries:
|
|
|
|
```typescript
|
|
// API endpoint - first line of defense
|
|
app.post('/orders', (req, res) => {
|
|
// Type check
|
|
if (typeof req.body.userId !== 'string') {
|
|
return res.status(400).json({ error: 'userId must be a string' });
|
|
}
|
|
|
|
// Existence check
|
|
if (!req.body.userId) {
|
|
return res.status(400).json({ error: 'userId is required' });
|
|
}
|
|
|
|
// Format validation
|
|
if (!isValidUUID(req.body.userId)) {
|
|
return res.status(400).json({ error: 'userId must be a valid UUID' });
|
|
}
|
|
|
|
// Proceed with valid data
|
|
orderService.createOrder(req.body);
|
|
});
|
|
```
|
|
|
|
### Layer 2: Business Logic Validation
|
|
|
|
Ensure data semantically makes sense for the operation:
|
|
|
|
```typescript
|
|
// Service layer - business rules
|
|
class OrderService {
|
|
async createOrder(data: OrderData) {
|
|
// Business validation
|
|
const user = await this.userRepo.findById(data.userId);
|
|
if (!user) {
|
|
throw new BusinessError('User does not exist');
|
|
}
|
|
|
|
if (!user.canPlaceOrders) {
|
|
throw new BusinessError('User is not allowed to place orders');
|
|
}
|
|
|
|
if (data.items.length === 0) {
|
|
throw new BusinessError('Order must have at least one item');
|
|
}
|
|
|
|
// Proceed with valid business state
|
|
return this.orderRepo.create(data);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Layer 3: Environment Guards
|
|
|
|
Add context-specific safeguards:
|
|
|
|
```typescript
|
|
// Repository layer - environment guards
|
|
class OrderRepository {
|
|
async create(order: Order) {
|
|
// Test environment guard
|
|
if (process.env.NODE_ENV === 'test' && !process.env.ALLOW_DB_WRITES) {
|
|
throw new Error('Database writes disabled in test environment');
|
|
}
|
|
|
|
// Production safety guard
|
|
if (order.total > 100000 && !order.managerApproval) {
|
|
throw new Error('Large orders require manager approval');
|
|
}
|
|
|
|
// Dangerous operation guard
|
|
if (order.userId === SYSTEM_USER_ID) {
|
|
throw new Error('Cannot create orders for system user');
|
|
}
|
|
|
|
return this.db.insert('orders', order);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Layer 4: Debug Instrumentation
|
|
|
|
Capture execution context for forensic analysis:
|
|
|
|
```typescript
|
|
// Logging layer - forensic evidence
|
|
class OrderRepository {
|
|
async create(order: Order) {
|
|
// Log entry for debugging
|
|
this.logger.debug('Creating order', {
|
|
orderId: order.id,
|
|
userId: order.userId,
|
|
itemCount: order.items.length,
|
|
total: order.total,
|
|
timestamp: new Date().toISOString(),
|
|
requestId: context.requestId
|
|
});
|
|
|
|
try {
|
|
const result = await this.db.insert('orders', order);
|
|
|
|
this.logger.info('Order created successfully', {
|
|
orderId: result.id,
|
|
duration: Date.now() - start
|
|
});
|
|
|
|
return result;
|
|
} catch (error) {
|
|
this.logger.error('Order creation failed', {
|
|
orderId: order.id,
|
|
error: error.message,
|
|
stack: error.stack,
|
|
order: JSON.stringify(order)
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Why Multiple Layers?
|
|
|
|
### Single Point Failure
|
|
|
|
```typescript
|
|
// Only one check - easily bypassed
|
|
function createOrder(data) {
|
|
if (!data.userId) throw new Error('userId required'); // Single check
|
|
// ...
|
|
}
|
|
|
|
// Direct repository call bypasses validation
|
|
orderRepository.create({ items: [] }); // No userId check!
|
|
```
|
|
|
|
### Multi-Layer Protection
|
|
|
|
```typescript
|
|
// Multiple checks - defense in depth
|
|
// Layer 1: API validates
|
|
// Layer 2: Service validates
|
|
// Layer 3: Repository validates
|
|
|
|
// Even if one is bypassed, others catch it
|
|
orderRepository.create({ items: [] });
|
|
// Repository throws: "userId is required"
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Strategy
|
|
|
|
When debugging, use this approach:
|
|
|
|
### 1. Trace the Data Flow
|
|
|
|
```markdown
|
|
User Input → API → Service → Repository → Database
|
|
```
|
|
|
|
### 2. Identify Checkpoints
|
|
|
|
```markdown
|
|
Where does this data pass through?
|
|
- API endpoint (Layer 1)
|
|
- Service method (Layer 2)
|
|
- Repository method (Layer 3)
|
|
- Database constraints (Layer 4)
|
|
```
|
|
|
|
### 3. Add Validation at Each
|
|
|
|
```markdown
|
|
For each checkpoint:
|
|
- What could be wrong at this point?
|
|
- What validation makes sense here?
|
|
- What error message helps debug?
|
|
```
|
|
|
|
### 4. Test Layer Independence
|
|
|
|
```markdown
|
|
Remove each layer one at a time:
|
|
- Does the bug still get caught?
|
|
- Which layer catches it?
|
|
- Is there a gap in coverage?
|
|
```
|
|
|
|
---
|
|
|
|
## Validation by Layer Type
|
|
|
|
| Layer | What to Validate | Example |
|
|
|-------|------------------|---------|
|
|
| Entry Point | Type, format, presence | `userId` is string, not empty |
|
|
| Business Logic | Semantic correctness | User exists, can place orders |
|
|
| Environment | Context-specific rules | Test mode restrictions |
|
|
| Data Access | Integrity constraints | Foreign keys, not null |
|
|
|
|
---
|
|
|
|
## Anti-Patterns
|
|
|
|
### Single Checkpoint Fallacy
|
|
|
|
```typescript
|
|
// BAD: One validation point
|
|
if (isValid(data)) {
|
|
// Assume valid everywhere else
|
|
}
|
|
```
|
|
|
|
### Validation in Tests Only
|
|
|
|
```typescript
|
|
// BAD: Tests validate, production doesn't
|
|
beforeEach(() => {
|
|
validateTestData(data); // This doesn't help production
|
|
});
|
|
```
|
|
|
|
### Trust After First Check
|
|
|
|
```typescript
|
|
// BAD: Validated once, trusted forever
|
|
const validatedData = validate(input);
|
|
// ... many lines later ...
|
|
process(validatedData); // Is it still valid?
|
|
```
|
|
|
|
---
|
|
|
|
## Checklist
|
|
|
|
After fixing any bug:
|
|
|
|
- [ ] Root cause identified
|
|
- [ ] Fix applied at source
|
|
- [ ] Layer 1 validation added (entry point)
|
|
- [ ] Layer 2 validation added (business logic)
|
|
- [ ] Layer 3 guards added (environment)
|
|
- [ ] Layer 4 logging added (instrumentation)
|
|
- [ ] Tested: removing any single layer still catches bug
|
|
- [ ] Bug is structurally impossible, not just fixed
|
|
|
|
---
|
|
|
|
## Related Skills
|
|
|
|
- `root-cause-tracing` - Use before defense-in-depth to find the actual source of the bug before adding multi-layer validation
|
|
- `systematic-debugging` - General debugging methodology that pairs with defense-in-depth for comprehensive bug resolution
|
|
- `owasp` - Security-specific validation patterns that complement defense-in-depth for security-sensitive code paths
|