moai-security-owasp
について
このエンタープライズ向けセキュリティスキルは、OWASP Top 10 2021の脆弱性に対するプロダクションレディな防御パターンを提供します。SQLインジェクション、XSS、CSRF攻撃に対する保護を提供し、安全なアクセス制御、入力検証、セキュリティヘッダーを実装しています。一般的なWeb脆弱性に対するエンタープライズレベルのセキュリティ対策が必要なWebアプリケーションを構築する際に、このスキルをご利用ください。
クイックインストール
Claude Code
推奨/plugin add https://github.com/modu-ai/moai-adkgit clone https://github.com/modu-ai/moai-adk.git ~/.claude/skills/moai-security-owaspこのコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします
ドキュメント
moai-security-owasp: OWASP Top 10 2021 Defense Patterns
Complete Protection Against OWASP Top 10 2021 Vulnerabilities
Trust Score: 9.8/10 | Version: 4.0.0 | Enterprise Mode | Last Updated: 2025-11-12
Overview
The OWASP Top 10 2021 represents the most critical web application security risks. This Skill provides production-ready defense patterns for all 10 categories with code examples and validation strategies.
When to use this Skill:
- Protecting against SQL injection, XSS, and CSRF attacks
- Implementing secure access control (BOLA/IDOR prevention)
- Validating and sanitizing user input
- Implementing security headers and CSP
- Building secure file upload handling
- Protecting against XXE and deserialization attacks
- Implementing cryptographic security
- Building secure authentication systems
- Preventing sensitive data exposure
- Implementing logging and monitoring
Level 1: OWASP Top 10 2021 Overview
Rankings & Changes
| Rank | 2021 Category | Focus | OWASP A# |
|---|---|---|---|
| 1 | Broken Access Control | BOLA, IDOR, BFLA | A01 |
| 2 | Cryptographic Failures | Weak encryption, hardcoded keys | A02 |
| 3 | Injection | SQL, OS, NoSQL, LDAP | A03 |
| 4 | Insecure Design | Missing threat modeling | A04 |
| 5 | Security Misconfiguration | Default creds, verbose errors | A05 |
| 6 | Vulnerable Components | Outdated dependencies | A06 |
| 7 | Authentication Failures | Weak MFA, session flaws | A07 |
| 8 | Data Integrity Failures | Insecure deserialization | A08 |
| 9 | Logging & Monitoring Failures | Missing audit trails | A09 |
| 10 | SSRF | Server-side request forgery | A10 |
Key Changes from 2017 to 2021
2017 → 2021:
- XSS merged into Injection (A03)
- Broken Access Control elevated to #1
- Insecure Deserialization → Data Integrity Failures
- XXE moved to Injection
- Using Components with Known Vulns → Vulnerable Components
- Insufficient Logging → Logging & Monitoring
- SSRF added to Top 10
Level 2: Defense Patterns for Each Category
A01: Broken Access Control (BOLA & IDOR)
BOLA (Broken Object Level Authorization):
// VULNERABLE: No object ownership check
app.get('/api/users/:userId', jwtAuth, (req, res) => {
const user = db.users.findById(req.params.userId);
res.json(user); // Attacker can access any user!
});
// SECURE: Verify ownership
app.get('/api/users/:userId', jwtAuth, (req, res) => {
const user = db.users.findById(req.params.userId);
// Check: User can only access their own data (or admin)
if (req.user.id !== user.id && req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(user);
});
// Multi-tenant: Always check tenant_id
app.get('/api/users/:userId', jwtAuth, (req, res) => {
const user = db.users.findById(req.params.userId);
// CRITICAL: Verify tenant ownership
if (user.tenant_id !== req.tenantId) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(user);
});
BFLA (Broken Function Level Authorization):
// VULNERABLE: No role check
app.post('/api/users/:userId/admin', jwtAuth, (req, res) => {
const user = db.users.findById(req.params.userId);
user.role = 'admin'; // Any user can become admin!
db.users.update(user);
res.json(user);
});
// SECURE: Verify admin role
app.post('/api/users/:userId/promote', jwtAuth, (req, res) => {
if (req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' });
}
const user = db.users.findById(req.params.userId);
user.role = 'admin';
db.users.update(user);
res.json(user);
});
A03: Injection (SQL, NoSQL, OS)
SQL Injection Prevention:
// VULNERABLE: String concatenation
const userId = req.query.userId;
const query = `SELECT * FROM users WHERE id = ${userId}`;
// Attack: userId = "1 OR 1=1" returns all users
db.query(query);
// SECURE: Parameterized queries
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]); // userId treated as value, not code
// SECURE: With ORM (Sequelize)
const user = await User.findByPk(userId);
// SECURE: With TypeORM
const user = await userRepository.createQueryBuilder()
.where('user.id = :id', { id: userId })
.getOne();
NoSQL Injection:
// VULNERABLE: Direct query construction
const query = { username: req.body.username };
const user = await db.collection('users').findOne(query);
// Attack: username = { $ne: '' } bypasses auth
// SECURE: Validation + parameterized
const schema = z.object({
username: z.string().email()
});
const validated = schema.parse(req.body);
const user = await db.collection('users').findOne({
username: validated.username
});
A07: Authentication Failures
Secure Password Validation:
// Rate limiting for login attempts
const loginAttempts = new Map();
app.post('/login', async (req, res) => {
const key = req.body.email;
const attempts = loginAttempts.get(key) || 0;
if (attempts >= 5) {
return res.status(429).json({
error: 'Too many attempts. Try again in 15 minutes.'
});
}
const user = await db.users.findByEmail(req.body.email);
const passwordValid = user &&
await bcrypt.compare(req.body.password, user.passwordHash);
if (!passwordValid) {
loginAttempts.set(key, attempts + 1);
// Always return same error (prevents user enumeration)
return res.status(401).json({ error: 'Invalid credentials' });
}
loginAttempts.delete(key);
// Check MFA if enabled
if (user.mfaEnabled) {
// Send OTP or prompt for TOTP
return res.json({ requiresMfa: true });
}
res.json({ token: jwt.sign({ id: user.id }, process.env.JWT_SECRET) });
});
A05: Security Misconfiguration
HTTP Security Headers:
const helmet = require('helmet');
app.use(helmet({
// Content Security Policy
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "https://trusted-cdn.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'"],
fontSrc: ["'self'"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
frameSrc: ["'none'"]
}
},
// HSTS: Force HTTPS
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
// Prevent clickjacking
frameguard: { action: 'deny' },
// Prevent MIME sniffing
noSniff: true,
// XSS Protection header
xssFilter: true,
// Referrer Policy
referrerPolicy: { policy: 'no-referrer' }
}));
// Disable server header
app.disable('x-powered-by');
Level 3: Advanced Input Validation
XSS Prevention (A03 Injection)
const { body, validationResult } = require('express-validator');
const sanitizeHtml = require('sanitize-html');
// 1. Input validation
const validateInput = [
body('comment')
.trim()
.isLength({ min: 1, max: 500 })
.escape() // Convert <, >, &, ", ' to entities
];
// 2. Sanitization (stronger than escape)
app.post('/comments', validateInput, (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors });
}
// Sanitize HTML
const sanitized = sanitizeHtml(req.body.comment, {
allowedTags: ['b', 'i', 'em', 'strong', 'p'],
allowedAttributes: {},
disallowedTagsMode: 'discard'
});
// Store sanitized version
db.comments.create({ content: sanitized });
res.json({ success: true });
});
// 3. Output encoding in templates (EJS/Handlebars)
// <%= comment %> auto-escapes HTML
// {{{ comment }}} does NOT escape (dangerous!)
CSRF Prevention
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(csrf({ cookie: false }));
// GET: Return CSRF token
app.get('/form', (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
// POST: Validate CSRF token
app.post('/form', csrf(), (req, res) => {
// Token automatically verified by middleware
// If invalid, returns 403
res.json({ success: true });
});
// Alternative: SameSite cookie
res.cookie('session', token, {
sameSite: 'strict', // No cross-site requests
secure: true, // HTTPS only
httpOnly: true // No JavaScript access
});
XXE (XML External Entity) Prevention
const xml2js = require('xml2js');
// VULNERABLE: External entities enabled by default
const parser = new xml2js.Parser();
parser.parseString(xmlInput, (err, result) => {
// Entity expansion attack possible
});
// SECURE: Disable external entities
const parser = new xml2js.Parser({
strict: false,
normalize: true,
normalizeTags: true,
// Libxmljs doesn't support DTD disabling,
// use alternative parser or validate schema
});
// BETTER: Use JSON instead of XML
// If XML required: validate against schema
Reference
Official Resources
- OWASP Top 10 2021: https://owasp.org/Top10/
- OWASP Top 10 2017: https://owasp.org/www-project-top-ten-2017/
- CWE Top 25: https://cwe.mitre.org/top25/
- NIST SP 800-63: https://pages.nist.gov/800-63-3/
Tools & Libraries
- helmet (7.0.x): https://helmetjs.github.io/
- express-validator (7.0.x): https://express-validator.github.io/
- sanitize-html (2.11.x): https://github.com/apostrophecms/sanitize-html
- sql-bricks (Parameterized queries): https://github.com/dresende/sql-bricks
- OWASP Dependency Check: https://owasp.org/www-project-dependency-check/
Common Vulnerabilities
| Vulnerability | CWE | Prevention |
|---|---|---|
| SQL Injection | CWE-89 | Parameterized queries |
| XSS | CWE-79 | Input validation, output encoding |
| CSRF | CWE-352 | CSRF tokens, SameSite cookies |
| XXE | CWE-611 | Disable external entities |
| BOLA | CWE-639 | Check ownership on every request |
Version: 4.0.0 Enterprise
Skill Category: Security (Vulnerability Defense)
Complexity: Medium
Time to Implement: 2-4 hours per category
Prerequisites: Web security fundamentals, Express.js knowledge
GitHub リポジトリ
関連スキル
evaluating-llms-harness
テストThis Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.
sglang
メタSGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.
cloudflare-turnstile
メタThis skill provides comprehensive guidance for implementing Cloudflare Turnstile as a CAPTCHA-alternative bot protection system. It covers integration for forms, login pages, API endpoints, and frameworks like React/Next.js/Hono, while handling invisible challenges that maintain user experience. Use it when migrating from reCAPTCHA, debugging error codes, or implementing token validation and E2E tests.
langchain
メタLangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.
