security-review skill
Usar este skill al agregar autenticación, manejar entradas de usuario, trabajar con secretos, crear endpoints de API o implementar funcionalidades de pago/sensibles. Proporciona lista de verificación y patrones de seguridad completos.
Is the security-review skill safe?
Clean: nothing in its files matched our rules. We read 1 file in the folder on 2026-09-28.
No findings.
Install the security-review skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/affaan-m/ECC.git /tmp/ECC mkdir -p ~/.claude/skills cp -r /tmp/ECC/docs/es/skills/security-review ~/.claude/skills/security-review
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Skill de Revisión de Seguridad
Este skill garantiza que todo el código siga las buenas prácticas de seguridad e identifica vulnerabilidades potenciales.
Cuándo Activar
- Implementar autenticación o autorización
- Manejar entrada de usuario o subida de archivos
- Crear nuevos endpoints de API
- Trabajar con secretos o credenciales
- Implementar funcionalidades de pago
- Almacenar o transmitir datos sensibles
- Integrar APIs de terceros
Lista de Verificación de Seguridad
1. Gestión de Secretos
FALLA: NUNCA Hacer Esto
const apiKey = "sk-proj-xxxxx" // Secreto hardcodeado
const dbPassword = "password123" // En el código fuentePASA: SIEMPRE Hacer Esto
const apiKey = process.env.OPENAI_API_KEY
const dbUrl = process.env.DATABASE_URL
// Verificar que los secretos existen
if (!apiKey) {
throw new Error('OPENAI_API_KEY not configured')
}Pasos de Verificación
- [ ] Sin claves de API, tokens ni contraseñas hardcodeadas
- [ ] Todos los secretos en variables de entorno
- [ ] .env.local en .gitignore
- [ ] Sin secretos en el historial de git
- [ ] Secretos de producción en la plataforma de hosting (Vercel, Railway)
2. Validación de Entrada
Siempre Validar la Entrada del Usuario
import { z } from 'zod'
// Definir esquema de validación
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
age: z.number().int().min(0).max(150)
})
// Validar antes de procesar
export async function createUser(input: unknown) {
try {
const validated = CreateUserSchema.parse(input)
return await db.users.create(validated)
} catch (error) {
if (error instanceof z.ZodError) {
return { success: false, errors: error.errors }
}
throw error
}
}Validación de Subida de Archivos
function validateFileUpload(file: File) {
// Verificar tamaño (máximo 5MB)
const maxSize = 5 * 1024 * 1024
if (file.size > maxSize) {
throw new Error('File too large (max 5MB)')
}
// Verificar tipo
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.type)) {
throw new Error('Invalid file type')
}
// Verificar extensión
const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']
const extension = file.name.toLowerCase().match(/\.[^.]+$/)?.[0]
if (!extension || !allowedExtensions.includes(extension)) {
throw new Error('Invalid file extension')
}
return true
}Pasos de Verificación
- [ ] Todas las entradas del usuario validadas con esquemas
- [ ] Subidas de archivos restringidas (tamaño, tipo, extensión)
- [ ] Sin uso directo de entrada del usuario en consultas
- [ ] Validación por lista blanca (no por lista negra)
- [ ] Los mensajes de error no revelan información sensible
3. Prevención de Inyección SQL
FALLA: NUNCA Concatenar SQL
// PELIGROSO - Vulnerabilidad de inyección SQL
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
await db.query(query)PASA: SIEMPRE Usar Consultas Parametrizadas
// Seguro - consulta parametrizada
const { data } = await supabase
.from('users')
.select('*')
.eq('email', userEmail)
// O con SQL puro
await db.query(
'SELECT * FROM users WHERE email = $1',
[userEmail]
)Pasos de Verificación
- [ ] Todas las consultas de base de datos usan consultas parametrizadas
- [ ] Sin concatenación de cadenas en SQL
- [ ] ORM/query builder usado correctamente
- [ ] Consultas de Supabase correctamente sanitizadas
4. Autenticación y Autorización
Manejo de Tokens JWT
// FALLA: INCORRECTO: localStorage (vulnerable a XSS)
localStorage.setItem('token', token)
// PASA: CORRECTO: cookies httpOnly
res.setHeader('Set-Cookie',
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)Verificaciones de Autorización
export async function deleteUser(userId: string, requesterId: string) {
// SIEMPRE verificar la autorización primero
const requester = await db.users.findUnique({
where: { id: requesterId }
})
if (requester.role !== 'admin') {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 403 }
)
}
// Proceder con la eliminación
await db.users.delete({ where: { id: userId } })
}Row Level Security (Supabase)
-- Habilitar RLS en todas las tablas
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
-- Los usuarios solo pueden ver sus propios datos
CREATE POLICY "Users view own data"
ON users FOR SELECT
USING (auth.uid() = id);
-- Los usuarios solo pueden actualizar sus propios datos
CREATE POLICY "Users update own data"
ON users FOR UPDATE
USING (auth.uid() = id);Pasos de Verificación
- [ ] Tokens almacenados en cookies httpOnly (no localStorage)
- [ ] Verificaciones de autorización antes de operaciones sensibles
- [ ] Row Level Security habilitado en Supabase
- [ ] Control de acceso basado en roles implementado
- [ ] Gestión de sesiones segura
5. Prevención de XSS
Sanitizar HTML
import DOMPurify from 'isomorphic-dompurify'
// SIEMPRE sanitizar HTML proporcionado por el usuario
function renderUserContent(html: string) {
const clean = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
ALLOWED_ATTR: []
})
return <div dangerouslySetInnerHTML={{ __html: clean }} />
}Content Security Policy
Comenzar con una política estricta y relajarla solo con un plan de eliminación documentado. No usar 'unsafe-inline' ni 'unsafe-eval' por defecto; neutralizan gran parte de la protección de CSP y deben tratarse como deuda de compatibilidad temporal.
// next.config.js
const securityHeaders = [
{
key: 'Content-Security-Policy',
value: `
default-src 'self';
base-uri 'self';
object-src 'none';
frame-ancestors 'none';
script-src 'self';
style-src 'self';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.example.com;
`.replace(/\s{2,}/g, ' ').trim()
}
]Pasos de Verificación
- [ ] HTML proporcionado por el usuario sanitizado
- [ ] Cabeceras CSP configuradas
- [ ] Sin renderizado de contenido dinámico no validado
- [ ] Protección XSS incorporada de React utilizada
6. Protección CSRF
Tokens CSRF
import { csrf } from '@/lib/csrf'
export async function POST(request: Request) {
const token = request.headers.get('X-CSRF-Token')
if (!csrf.verify(token)) {
return NextResponse.json(
{ error: 'Invalid CSRF token' },
{ status: 403 }
)
}
// Procesar solicitud
}Cookies SameSite
res.setHeader('Set-Cookie',
`session=${sessionId}; HttpOnly; Secure; SameSite=Strict`)Pasos de Verificación
- [ ] Tokens CSRF en operaciones que cambian estado
- [ ] SameSite=Strict en todas las cookies
- [ ] Patrón de doble envío de cookie implementado
7. Limitación de Velocidad
Limitación de Velocidad en API
import rateLimit from 'express-rate-limit'
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 100, // 100 solicitudes por ventana
message: 'Too many requests'
})
// Aplicar a rutas
app.use('/api/', limiter)Operaciones Costosas
// Limitación agresiva para búsquedas
const searchLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minuto
max: 10, // 10 solicitudes por minuto
message: 'Too many search requests'
})
app.use('/api/search', searchLimiter)Pasos de Verificación
- [ ] Limitación de velocidad en todos los endpoints de API
- [ ] Límites más estrictos en operaciones costosas
- [ ] Limitación de velocidad basada en IP
- [ ] Limitación de velocidad basada en usuario (autenticado)
8. Exposición de Datos Sensibles
Logging
// FALLA: INCORRECTO: Registrar datos sensibles
console.log('User login:', { email, password })
console.log('Payment:', { cardNumber, cvv })
// PASA: CORRECTO: Redactar datos sensibles
console.log('User login:', { email, userId })
console.log('Payment:', { last4: card.last4, userId })More skills from affaan-m/ECC
- AaccessibilityWCAG 2.2 レベル AA 標準を用いてインクルーシブなデジタルプロダクトを設計・実装・監査します。Web 用のセマンティック ARIA および Web・ネイティブプラットフォーム(iOS/Android)のアクセシビリティトレイトを生成するために使用します。
- Aagent-architecture-auditエージェントおよび LLM アプリケーション向けのフルスタック診断。12 層のエージェントスタックにおけるラッパーリグレッション、メモリ汚染、ツール規律の失敗、隠れた修復ループ、レンダリング破損を監査します。重要度順の発見事項とコードファーストの修正を生成します。エージェントアプリケーション、自律ループ、または LLM を活用した機能を構築する開発者に必須です。
- Aagent-evalカスタムタスクでコーディングエージェント(Claude Code、Aider、Codex など)をヘッドツーヘッドで比較し、合格率、コスト、時間、一貫性のメトリクスを測定します
- Aagent-harness-constructionAI エージェントのアクション空間、ツール定義、観測フォーマットを設計・最適化して完了率を向上させます。
- Aagent-introspection-debuggingStructured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.
- Aagent-introspection-debuggingキャプチャ、診断、封じ込め回復、内省レポートを使用した AI エージェント障害のための構造化された自己デバッグワークフロー。
- Aagent-payment-x402タスクごとのバジェット、支出コントロール、ノンカストディアルウォレットを備えた x402 決済実行を AI エージェントに追加します。agentwallet-sdk を通じて Base をサポートし、OKX Payments / OKX エージェント決済プロトコルを通じて X Layer をサポートします。
- Aagent-sortBuild an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.
- Aagent-sort並行リポジトリ対応のレビューパスを使用して、スキル、コマンド、ルール、フック、エクストラを DAILY と LIBRARY のバケットに分類することで、特定のリポジトリ向けのエビデンスに基づいた ECC インストール計画を構築します。プロジェクトが完全なバンドルをロードする代わりに実際に必要なものに ECC をトリミングする必要がある場合に使用します。
- Aagentic-engineeringOperate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when AI agents perform most implementation work and humans enforce quality and risk controls.
- Aagentic-engineering評価ファースト実行、分解、コスト対応モデルルーティングを使用してエージェニックエンジニアとして動作します。
- Aagentic-osClaude Code 上に永続的なマルチエージェントオペレーティングシステムを構築します。カーネルアーキテクチャ、スペシャリストエージェント、スラッシュコマンド、ファイルベースのメモリ、スケジュールされた自動化、外部データベースなしの状態管理をカバーします。