.agents/skills/security-best-practices/SKILL.md
Implement security best practices for web applications and infrastructure. Use when securing APIs, preventing common vulnerabilities, or implementing security policies. Handles HTTPS, CORS, XSS, SQL Injection, CSRF, rate limiting, and OWASP Top 10.
npx skillsauth add RomainGRAS42/Procedio-AI security-best-practicesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Express.js 보안 미들웨어:
import express from 'express';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
const app = express();
// Helmet: 보안 헤더 자동 설정
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "https://trusted-cdn.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "https://api.example.com"],
fontSrc: ["'self'", "https:", "data:"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
frameSrc: ["'none'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
// HTTPS 강제
app.use((req, res, next) => {
if (process.env.NODE_ENV === 'production' && !req.secure) {
return res.redirect(301, `https://${req.headers.host}${req.url}`);
}
next();
});
// Rate Limiting (DDoS 방지)
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15분
max: 100, // IP당 최대 100 요청
message: 'Too many requests from this IP, please try again later.',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api/', limiter);
// Auth 엔드포인트는 더 엄격하게
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // 15분에 5번만
skipSuccessfulRequests: true // 성공 요청은 카운트하지 않음
});
app.use('/api/auth/login', authLimiter);
Joi 검증:
import Joi from 'joi';
const userSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).pattern(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/).required(),
name: Joi.string().min(2).max(50).required()
});
app.post('/api/users', async (req, res) => {
// 1. Input 검증
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
// 2. SQL Injection 방지: Parameterized Queries
// ❌ 나쁜 예
// db.query(`SELECT * FROM users WHERE email = '${email}'`);
// ✅ 좋은 예
const user = await db.query('SELECT * FROM users WHERE email = ?', [value.email]);
// 3. XSS 방지: Output Encoding
// React/Vue는 자동으로 escape, 그 외는 라이브러리 사용
import DOMPurify from 'isomorphic-dompurify';
const sanitized = DOMPurify.sanitize(userInput);
res.json({ user: sanitized });
});
CSRF Token:
import csrf from 'csurf';
import cookieParser from 'cookie-parser';
app.use(cookieParser());
// CSRF protection
const csrfProtection = csrf({ cookie: true });
// CSRF 토큰 제공
app.get('/api/csrf-token', csrfProtection, (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
// 모든 POST/PUT/DELETE 요청에 CSRF 검증
app.post('/api/*', csrfProtection, (req, res, next) => {
next();
});
// 클라이언트에서 사용
// fetch('/api/users', {
// method: 'POST',
// headers: {
// 'CSRF-Token': csrfToken
// },
// body: JSON.stringify(data)
// });
.env (절대 커밋하지 않음):
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# JWT
ACCESS_TOKEN_SECRET=your-super-secret-access-token-key-min-32-chars
REFRESH_TOKEN_SECRET=your-super-secret-refresh-token-key-min-32-chars
# API Keys
STRIPE_SECRET_KEY=sk_test_xxx
SENDGRID_API_KEY=SG.xxx
Kubernetes Secrets:
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
type: Opaque
stringData:
database-url: postgresql://user:password@postgres:5432/mydb
jwt-secret: your-jwt-secret
// 환경변수에서 읽기
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) {
throw new Error('DATABASE_URL environment variable is required');
}
JWT + Refresh Token Rotation:
// Access Token 짧게 (15분)
const accessToken = jwt.sign({ userId }, ACCESS_SECRET, { expiresIn: '15m' });
// Refresh Token 길게 (7일), DB에 저장
const refreshToken = jwt.sign({ userId }, REFRESH_SECRET, { expiresIn: '7d' });
await db.refreshToken.create({
userId,
token: refreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});
// Refresh Token Rotation: 사용 시마다 새로 발급
app.post('/api/auth/refresh', async (req, res) => {
const { refreshToken } = req.body;
const payload = jwt.verify(refreshToken, REFRESH_SECRET);
// 기존 토큰 무효화
await db.refreshToken.delete({ where: { token: refreshToken } });
// 새 토큰 발급
const newAccessToken = jwt.sign({ userId: payload.userId }, ACCESS_SECRET, { expiresIn: '15m' });
const newRefreshToken = jwt.sign({ userId: payload.userId }, REFRESH_SECRET, { expiresIn: '7d' });
await db.refreshToken.create({
userId: payload.userId,
token: newRefreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});
res.json({ accessToken: newAccessToken, refreshToken: newRefreshToken });
});
- [ ] A01: Broken Access Control - RBAC, 권한 검증
- [ ] A02: Cryptographic Failures - HTTPS, 암호화
- [ ] A03: Injection - Parameterized Queries, Input Validation
- [ ] A04: Insecure Design - Security by Design
- [ ] A05: Security Misconfiguration - Helmet, 기본 비밀번호 변경
- [ ] A06: Vulnerable Components - npm audit, 정기 업데이트
- [ ] A07: Authentication Failures - 강력한 인증, MFA
- [ ] A08: Data Integrity Failures - 서명 검증, CSRF 방지
- [ ] A09: Logging Failures - 보안 이벤트 로깅
- [ ] A10: SSRF - 외부 요청 검증
#security #OWASP #HTTPS #CORS #XSS #SQL-injection #CSRF #infrastructure
tools
YouTube thumbnail design with specific dimensions, contrast rules, and mobile preview optimization. Covers safe zones, text placement, face expression psychology, and A/B testing. Use for: YouTube thumbnails, video cover images, click-through optimization. Triggers: youtube thumbnail, thumbnail design, video thumbnail, click through rate, ctr optimization, youtube cover, video cover image, thumbnail maker, thumbnail tips, youtube design, video preview image
tools
Web search and content extraction with Tavily and Exa via inference.sh CLI. Apps: Tavily Search, Tavily Extract, Exa Search, Exa Answer, Exa Extract. Capabilities: AI-powered search, content extraction, direct answers, research. Use for: research, RAG pipelines, fact-checking, content aggregation, agents. Triggers: web search, tavily, exa, search api, content extraction, research, internet search, ai search, search assistant, web scraping, rag, perplexity alternative
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
development
Conduct WCAG 2.2 accessibility audits with automated testing, manual verification, and remediation guidance. Use when auditing websites for accessibility, fixing WCAG violations, or implementing accessible design patterns.