security
Overview
Enforces zero-trust defense-in-depth, OWASP API Top 10 mitigation, cryptographic hardening, sensitive data leakage protection, and AI/LLM safety across all services, endpoints, and agent integrations.
When to Use
Activate whenever writing authentication, authorization, session management, database queries, cryptography, external API integrations, user input handling, or agent tool calling.
Rules & Patterns
Negative Constraints (What NOT to Do)
- NEVER use standard string comparison (
===) for secrets/hashes: Always use crypto.timingSafeEqual to prevent timing attacks.
- NEVER store sensitive JWT access/refresh tokens in
localStorage: Store tokens in httpOnly, Secure, SameSite=Strict cookies.
- NEVER return raw database/internal error messages or stack traces to the client: Return standardized generic error codes (
INTERNAL_SERVER_ERROR) and log details internally.
- NEVER trust client-provided IDs for authorization without tenant/ownership checks: Always verify
where: { id, userId: session.userId } to prevent Broken Object Level Authorization (BOLA/IDOR).
- NEVER disable CSRF protection, CORS allow-all (
*), or TLS verification (NODE_TLS_REJECT_UNAUTHORIZED=0) in production: Always enforce strict origin whitelists and HTTPS.
- NEVER pass un-sanitized third-party content directly into system prompts or shell execution: Treat all external data as potentially adversarial.
OWASP Top 10 for Modern APIs & Full-Stack
1. Injection (SQL, NoSQL, Command)
- Always use parameterized queries — never concatenate user input into SQL or shell commands.
- Use ORMs (Prisma, Drizzle, SQLAlchemy) with strict schema validation.
- Validate and sanitize all user input before processing.
2. Broken Object Level Authorization (BOLA / IDOR)
Validate user ownership on EVERY database read, update, or delete:
// [GOOD] Scoped to authenticated user
const doc = await db.document.findFirst({
where: { id: documentId, tenantId: session.tenantId }
});
3. Broken Authentication & Session Management
- Use Argon2id or bcrypt (cost factor ≥ 12) for password hashing.
- Short-lived access tokens (15 min) + secure HTTP-only refresh tokens.
- Enforce rate limiting and brute-force lockouts on auth endpoints.
4. SSRF (Server-Side Request Forgery)
- Restrict server-side URL fetching: validate URL scheme (
https: only), resolve IP, and block private CIDR blocks (10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 192.168.0.0/16).
5. Security Misconfiguration & Headers
Enforce modern production security headers:
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Strict-Transport-Security: max-age=31536000; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
AI Agent & LLM Security Invariants
When building AI workflows, tools, or MCP servers:
- Prompt Injection Defense:
- Clearly delineate untrusted user/web content using boundary markers (e.g.
<untrusted_content> tags).
- Never allow untrusted content to override system instructions or tool execution permissions.
- Tool Execution Boundaries:
- Destructive operations (database drops, file deletions, payment triggers) MUST require explicit user confirmation.
- Restrict file system tools to the workspace root — block directory traversal (
../).
- Secret Masking & Output Sanitization:
- Scrub API keys (
sk-..., Bearer ...), tokens, and credentials before writing to agent logs or step summaries.
Code Examples
Timing-Safe Secret Verification
import crypto from 'node:crypto';
export function verifyWebhookSignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = Buffer.from(hmac.update(payload).digest('hex'), 'utf8');
const sigBuffer = Buffer.from(signature, 'utf8');
if (digest.length !== sigBuffer.length) return false;
return crypto.timingSafeEqual(digest, sigBuffer);
}
Safe SSRF Prevention Wrapper
import dns from 'node:dns/promises';
export async function validateSafeUrl(urlString: string): Promise<URL> {
const parsed = new URL(urlString);
if (parsed.protocol !== 'https:') {
throw new Error('Only HTTPS protocol is permitted');
}
const { address } = await dns.lookup(parsed.hostname);
if (
address.startsWith('127.') ||
address.startsWith('10.') ||
address.startsWith('192.168.') ||
address === '169.254.169.254'
) {
throw new Error('Access to private/metadata IP addresses is blocked');
}
return parsed;
}
Validation Checklist
Common Mistakes
- Trusting client-side claims: Checking role or permissions only on the frontend without server-side validation.
- Timing attacks on tokens: Comparing tokens with
token === expectedToken instead of timingSafeEqual.
- Exposing internal stack traces: Returning full error objects to client in production.
- Unvalidated redirects / URLs: Allowing arbitrary URLs in redirect or fetch parameters.
Integration Notes
- Runs in the REVIEW phase for every backend route, auth flow, and database mutation.
- Integrates with
engineering-workflow during Phase 5 (5-axis quality gate).
- Pairs with
system-design to mandate secure network boundaries and authorization layers.
1---2name: security3description: Application and AI agent security skill. Enforces zero-trust defense-in-depth, OWASP Top 10 mitigation, prompt injection defense, and secure tool execution.4---56# security78## Overview910Enforces zero-trust defense-in-depth, OWASP API Top 10 mitigation, cryptographic hardening, sensitive data leakage protection, and AI/LLM safety across all services, endpoints, and agent integrations.1112## When to Use1314Activate whenever writing authentication, authorization, session management, database queries, cryptography, external API integrations, user input handling, or agent tool calling.1516## Rules & Patterns1718### Negative Constraints (What NOT to Do)19201. **NEVER use standard string comparison (`===`) for secrets/hashes**: Always use `crypto.timingSafeEqual` to prevent timing attacks.212. **NEVER store sensitive JWT access/refresh tokens in `localStorage`**: Store tokens in `httpOnly`, `Secure`, `SameSite=Strict` cookies.223. **NEVER return raw database/internal error messages or stack traces to the client**: Return standardized generic error codes (`INTERNAL_SERVER_ERROR`) and log details internally.234. **NEVER trust client-provided IDs for authorization without tenant/ownership checks**: Always verify `where: { id, userId: session.userId }` to prevent Broken Object Level Authorization (BOLA/IDOR).245. **NEVER disable CSRF protection, CORS allow-all (`*`), or TLS verification (`NODE_TLS_REJECT_UNAUTHORIZED=0`) in production**: Always enforce strict origin whitelists and HTTPS.256. **NEVER pass un-sanitized third-party content directly into system prompts or shell execution**: Treat all external data as potentially adversarial.2627---2829### OWASP Top 10 for Modern APIs & Full-Stack3031#### 1. Injection (SQL, NoSQL, Command)3233- Always use parameterized queries — never concatenate user input into SQL or shell commands.34- Use ORMs (Prisma, Drizzle, SQLAlchemy) with strict schema validation.35- Validate and sanitize all user input before processing.3637#### 2. Broken Object Level Authorization (BOLA / IDOR)3839- Validate user ownership on EVERY database read, update, or delete:4041 ```typescript42 // [GOOD] Scoped to authenticated user43 const doc = await db.document.findFirst({44 where: { id: documentId, tenantId: session.tenantId }45 });46 ```4748#### 3. Broken Authentication & Session Management4950- Use Argon2id or bcrypt (cost factor ≥ 12) for password hashing.51- Short-lived access tokens (15 min) + secure HTTP-only refresh tokens.52- Enforce rate limiting and brute-force lockouts on auth endpoints.5354#### 4. SSRF (Server-Side Request Forgery)5556- Restrict server-side URL fetching: validate URL scheme (`https:` only), resolve IP, and block private CIDR blocks (`10.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `192.168.0.0/16`).5758#### 5. Security Misconfiguration & Headers5960Enforce modern production security headers:6162```http63Content-Security-Policy: default-src 'self'64X-Content-Type-Options: nosniff65X-Frame-Options: DENY66Strict-Transport-Security: max-age=31536000; includeSubDomains67Referrer-Policy: strict-origin-when-cross-origin68Permissions-Policy: camera=(), microphone=(), geolocation=()69```7071---7273### AI Agent & LLM Security Invariants7475When building AI workflows, tools, or MCP servers:76771. **Prompt Injection Defense**:78 - Clearly delineate untrusted user/web content using boundary markers (e.g. `<untrusted_content>` tags).79 - Never allow untrusted content to override system instructions or tool execution permissions.802. **Tool Execution Boundaries**:81 - Destructive operations (database drops, file deletions, payment triggers) MUST require explicit user confirmation.82 - Restrict file system tools to the workspace root — block directory traversal (`../`).833. **Secret Masking & Output Sanitization**:84 - Scrub API keys (`sk-...`, `Bearer ...`), tokens, and credentials before writing to agent logs or step summaries.8586---8788## Code Examples8990### Timing-Safe Secret Verification9192```javascript93import crypto from 'node:crypto';9495export function verifyWebhookSignature(payload, signature, secret) {96 const hmac = crypto.createHmac('sha256', secret);97 const digest = Buffer.from(hmac.update(payload).digest('hex'), 'utf8');98 const sigBuffer = Buffer.from(signature, 'utf8');99100 if (digest.length !== sigBuffer.length) return false;101 return crypto.timingSafeEqual(digest, sigBuffer);102}103```104105### Safe SSRF Prevention Wrapper106107```typescript108import dns from 'node:dns/promises';109110export async function validateSafeUrl(urlString: string): Promise<URL> {111 const parsed = new URL(urlString);112 if (parsed.protocol !== 'https:') {113 throw new Error('Only HTTPS protocol is permitted');114 }115116 const { address } = await dns.lookup(parsed.hostname);117 if (118 address.startsWith('127.') ||119 address.startsWith('10.') ||120 address.startsWith('192.168.') ||121 address === '169.254.169.254'122 ) {123 throw new Error('Access to private/metadata IP addresses is blocked');124 }125126 return parsed;127}128```129130---131132## Validation Checklist133134- [ ] All database queries parameterized or managed by type-safe ORM.135- [ ] BOLA/IDOR prevented: all entity queries scoped by tenant/user id.136- [ ] Cookies set with `HttpOnly`, `Secure`, and `SameSite=Strict` or `Lax`.137- [ ] Passwords hashed with Argon2id / bcrypt.138- [ ] Security headers active in middleware/reverse proxy.139- [ ] No secrets or tokens checked into source control or exposed in logs.140141---142143## Common Mistakes144145- **Trusting client-side claims**: Checking role or permissions only on the frontend without server-side validation.146- **Timing attacks on tokens**: Comparing tokens with `token === expectedToken` instead of `timingSafeEqual`.147- **Exposing internal stack traces**: Returning full error objects to client in production.148- **Unvalidated redirects / URLs**: Allowing arbitrary URLs in redirect or fetch parameters.149150---151152## Integration Notes153154- Runs in the REVIEW phase for every backend route, auth flow, and database mutation.155- Integrates with `engineering-workflow` during Phase 5 (5-axis quality gate).156- Pairs with `system-design` to mandate secure network boundaries and authorization layers.