security-best-practices
42
总安装量
43
周安装量
#4960
全站排名
安装命令
npx skills add https://github.com/supercent-io/skills-template --skill security-best-practices
Agent 安装分布
opencode
34
gemini-cli
31
claude-code
30
antigravity
24
github-copilot
24
Skill 文档
Security Best Practices
When to use this skill
- ì ê· íë¡ì í¸: ì²ìë¶í° ë³´ì ê³ ë ¤
- ë³´ì ê°ì¬: ì·¨ì½ì ì ê² ë° ìì
- API ê³µê°: ì¸ë¶ ì ê·¼ API ë³´ì ê°í
- ì»´íë¼ì´ì¸ì¤: GDPR, PCI-DSS ë± ì¤ì
Instructions
Step 1: HTTPS ê°ì ë° ë³´ì í¤ë
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);
Step 2: Input Validation (SQL Injection, XSS ë°©ì§)
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 });
});
Step 3: CSRF ë°©ì§
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)
// });
Step 4: Secrets ê´ë¦¬
.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');
}
Step 5: API ì¸ì¦ ë³´ì
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 });
});
Constraints
íì ê·ì¹ (MUST)
- HTTPS Only: íë¡ëì ìì HTTPS íì
- Secrets ë¶ë¦¬: íê²½ë³ìë¡ ê´ë¦¬, ì ë ì½ëì íëì½ë© ê¸ì§
- Input Validation: 모ë ì¬ì©ì ì ë ¥ ê²ì¦
- Parameterized Queries: SQL Injection ë°©ì§
- Rate Limiting: DDoS ë°©ì§
ê¸ì§ ì¬í (MUST NOT)
- eval() ì¬ì© ê¸ì§: ì½ë ì¸ì ì ìí
- innerHTML ì§ì ì¬ì©: XSS ìí
- Secrets 커ë°: .env íì¼ ì ë 커ë°íì§ ìì
OWASP Top 10 ì²´í¬ë¦¬ì¤í¸
- [ ] 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 - ì¸ë¶ ìì² ê²ì¦
Best practices
- Principle of Least Privilege: ìµì ê¶í ë¶ì¬
- Defense in Depth: ë¤ì¸µ ë³´ì
- Security Audits: ì 기ì ì¸ ë³´ì ì ê²
References
Metadata
ë²ì
- íì¬ ë²ì : 1.0.0
- ìµì¢ ì ë°ì´í¸: 2025-01-01
- í¸í íë«í¼: Claude, ChatGPT, Gemini
ê´ë ¨ ì¤í¬
íê·¸
#security #OWASP #HTTPS #CORS #XSS #SQL-injection #CSRF #infrastructure