analytics-metrics
Build data visualization and analytics dashboards. Use when creating charts, KPI displays, metrics dashboards, or dataโฆ
Implement secure coding practices following OWASP Top 10. Use when preventing security vulnerabilities, implementing authentication, securing APIs, or conducting security reviews. Triggers on OWASP, security, XSS, SQL injection, CSRF, authentication security, secure coding,
Claude Code
$ npx -y skills add hoodini/ai-agents-skills --skill owasp-security --agent claude-code
Codex
$ npx skills add hoodini/ai-agents-skills --skill owasp-security -a codex -y
Cursor
$ npx skills add hoodini/ai-agents-skills --skill owasp-security -a cursor -y
Gemini CLI
$ npx skills add hoodini/ai-agents-skills --skill owasp-security -a gemini-cli -y
GitHub Copilot
$ npx skills add hoodini/ai-agents-skills --skill owasp-security -a github-copilot -y
OpenCode
$ npx skills add hoodini/ai-agents-skills --skill owasp-security -a opencode -y
Windsurf
$ npx skills add hoodini/ai-agents-skills --skill owasp-security -a windsurf -y
name: owasp-security description: Implement secure coding practices following OWASP Top 10. Use when preventing security vulnerabilities, implementing authentication, securing APIs, or conducting security reviews. Triggers on OWASP, security, XSS, SQL injection, CSRF, authentication security, secure coding, vulnerability.
Prevent common security vulnerabilities in web applications.
| # | Vulnerability | Prevention | |---|---------------|------------| | A01 | Broken Access Control | Proper authorization checks | | A02 | Cryptographic Failures | Strong encryption, secure storage | | A03 | Injection | Input validation, parameterized queries | | A04 | Insecure Design | Threat modeling, secure patterns | | A05 | Security Misconfiguration | Hardened configs, no defaults | | A06 | Vulnerable Components | Dependency scanning, updates | | A07 | Auth Failures | MFA, secure session management | | A08 | Data Integrity Failures | Input validation, signed updates | | A09 | Logging Failures | Comprehensive audit logs | | A10 | SSRF | URL validation, allowlists |
// โ BAD: No authorization check
app.get('/api/users/:id', async (req, res) => {
const user = await db.users.findById(req.params.id);
res.json(user);
});
// โ
GOOD: Verify ownership
app.get('/api/users/:id', authenticate, async (req, res) => {
const userId = req.params.id;
// Users can only access their own data
if (req.user.id !== userId && req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' });
}
const user = await db.users.findById(userId);
res.json(user);
});
// โ
GOOD: Role-based access control (RBAC)
const requireRole = (...roles: string[]) => {
return (req: Request, res: Response, next: NextFunction) => {
if (!roles.includes(req.user?.role)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
};
app.delete('/api/posts/:id', authenticate, requireRole('admin', 'moderator'), deletePost);// โ BAD: Predictable IDs exposed
GET /api/invoices/1001
GET /api/invoices/1002 // Can enumerate others' invoices
// โ
GOOD: Use UUIDs + ownership check
app.get('/api/invoices/:id', authenticate, async (req, res) => {
const invoice = await db.invoices.findOne({
id: req.params.id,
userId: req.user.id, // Enforce ownership
});
if (!invoice) {
return res.status(404).json({ error: 'Not found' });
}
res.json(invoice);
});import bcrypt from 'bcrypt';
import crypto from 'crypto';
// โ
Hash passwords with bcrypt
const SALT_ROUNDS = 12;
async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, SALT_ROUNDS);
}
async function verifyPassword(password: string, hash: string): Promise<boolean> {
return bcrypt.compare(password, hash);
}
// โ
Secure token generation
function generateSecureToken(length = 32): string {
return crypto.randomBytes(length).toString('hex');
}
// โ
Encrypt sensitive data
const ALGORITHM = 'aes-256-gcm';
const KEY = crypto.scryptSync(process.env.ENCRYPTION_KEY!, 'salt', 32);
function encrypt(text: string): { encrypted: string; iv: string; tag: string } {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(ALGORITHM, KEY, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
encrypted,
iv: iv.toString('hex'),
tag: cipher.getAuthTag().toString('hex'),
};
}
function decrypt(encrypted: string, iv: string, tag: string): string {
const decipher = crypto.createDecipheriv(ALGORITHM, KEY, Buffer.from(iv, 'hex'));
decipher.setAuthTag(Buffer.from(tag, 'hex'));
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}import helmet from 'helmet';
app.use(helmet());
app.use(helmet.hsts({ maxAge: 31536000, includeSubDomains: true }));
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'strict-dynamic'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'"],
fontSrc: ["'self'"],
objectSrc: ["'none'"],
frameAncestors: ["'none'"],
},
}));// โ BAD: String concatenation
const query = `SELECT * FROM users WHERE email = '${email}'`;
// โ
GOOD: Parameterized queries
// With Prisma
const user = await prisma.user.findUnique({ where: { email } });
// With raw SQL (parameterized)
const user = await db.query('SELECT * FROM users WHERE email = $1', [email]);
// With Knex
const user = await knex('users').where({ email }).first();// โ BAD: Direct user input in query
const user = await User.findOne({ username: req.body.username });
// Attack: { "username": { "$gt": "" } } returns first user
// โ
GOOD: Validate input type
import { z } from 'zod';
const loginSchema = z.object({
username: z.string().min(3).max(50),
password: z.string().min(8),
});
app.post('/login', async (req, res) => {
const { username, password } = loginSchema.parse(req.body);
const user = await User.findOne({ username: String(username) });
// ...
});import { execFile } from 'child_process';
// โ BAD: Shell injection
exec(`convert ${userInput} output.png`); // userInput: "; rm -rf /"
// โ
GOOD: Use execFile with array args
execFile('convert', [userInput, 'output.png'], (error, stdout) => {
// Safe - arguments are not shell-interpreted
});
// โ
GOOD: Validate and sanitize
const allowedFormats = ['png', 'jpg', 'gif'];
if (!allowedFormats.inclu๐ง AI Agent Skills Repository - A curated collection of specialized skills for AI coding agents (Claude Code, GitHub Copilot, Cursor, Windsurf). Created by Yuval Avidani using GitHub Copilot via VS Code Insiders.
Build data visualization and analytics dashboards. Use when creating charts, KPI displays, metrics dashboards, or dataโฆ
Manage AWS accounts, organizations, IAM, and billing. Use when setting up AWS Organizations, managing IAM policies, controllingโฆ
Build a new AI agent on AWS and deploy it easily, OR wrap and deploy an agent you already have, using the Amazon Bedrockโฆ
Build AI agents with the Strands Agents SDK - the open-source framework (the agent "brain") for writing agent logic, tools, andโฆ
Build fast applications with Bun JavaScript runtime. Use when creating Bun projects, using Bun APIs, bundling, testing, orโฆ
Build a premium cinematic landing page with mouse-scrub video hero and brand-driven narrative-arc sections. Use whenever the userโฆ
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, orโฆ
Ask which skill or flow fits your situation. A router over the skills in this repo.