security-first

Security First - Shield Your Code

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "security-first" with this command: npx skills add j0kz/mcp-agents/j0kz-mcp-agents-security-first

Security First - Shield Your Code

🎯 When to Use This Skill

Use BEFORE:

  • Deploying to production

  • Handling sensitive data

  • Opening API endpoints

  • Processing user input

  • Storing passwords

  • Accepting file uploads

  • Going live with payments

⚡ 5-Minute Security Audit

WITH MCP (Security Scanner):

"Run complete security audit on my codebase" "Find and fix all OWASP Top 10 vulnerabilities"

WITHOUT MCP - Quick Scan:

1. Find hardcoded secrets (CRITICAL!)

grep -r "password|secret|token|api[_-]key" --include=".js" --include=".env" | grep -v ".example"

2. Check for SQL injection

grep -r "query.+|query.${" --include="*.js"

3. Find eval/exec usage

grep -r "eval(|exec(|Function(" --include="*.js"

4. Check dependencies

npm audit # or pip check, bundle audit

5. Find unvalidated input

grep -r "req.body|req.query|req.params" --include="*.js" | grep -v "validate|sanitize"

🛡️ OWASP Top 10 Checklist (2024)

  1. Injection (SQL, NoSQL, Command) 💉

Vulnerable Code:

// ❌ NEVER DO THIS const query = SELECT * FROM users WHERE id = ${req.params.id}; db.query(query); // SQL Injection!

// ❌ Command injection exec(ping ${userInput}); // Dangerous!

Secure Code:

// ✅ Parameterized queries const query = 'SELECT * FROM users WHERE id = ?'; db.query(query, [req.params.id]);

// ✅ For MongoDB User.findOne({ _id: sanitize(req.params.id) });

// ✅ Command execution const { spawn } = require('child_process'); spawn('ping', [userInput], { shell: false });

  1. Broken Authentication 🔐

Security Checklist:

// ✅ Strong password requirements function validatePassword(password) { const requirements = { minLength: 12, hasUpperCase: /[A-Z]/.test(password), hasLowerCase: /[a-z]/.test(password), hasNumbers: /\d/.test(password), hasSpecialChar: /[!@#$%^&*]/.test(password), notCommon: !commonPasswords.includes(password), };

return Object.values(requirements).every(req => req); }

// ✅ Secure session management app.use( session({ secret: process.env.SESSION_SECRET, // From environment resave: false, saveUninitialized: false, cookie: { secure: true, // HTTPS only httpOnly: true, // No JS access maxAge: 3600000, // 1 hour sameSite: 'strict', // CSRF protection }, }) );

// ✅ Rate limiting const rateLimit = require('express-rate-limit'); const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5, // 5 attempts message: 'Too many login attempts', }); app.post('/login', loginLimiter, loginHandler);

  1. Sensitive Data Exposure 🔒

Never Store in Code:

// ❌ WRONG const API_KEY = 'sk_live_abcd1234'; const DB_PASSWORD = 'admin123';

// ✅ CORRECT - Use environment variables const API_KEY = process.env.API_KEY; const DB_PASSWORD = process.env.DB_PASSWORD;

// ✅ Use .env file (never commit!) require('dotenv').config();

// ✅ Encrypt sensitive data at rest const crypto = require('crypto'); const algorithm = 'aes-256-gcm';

function encrypt(text) { const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(algorithm, key, iv);

let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex');

const authTag = cipher.getAuthTag();

return { encrypted, iv: iv.toString('hex'), authTag: authTag.toString('hex'), }; }

  1. XML External Entities (XXE) 📄

// ❌ Vulnerable XML parsing const libxmljs = require('libxmljs'); const doc = libxmljs.parseXml(userInput); // XXE vulnerable!

// ✅ Safe XML parsing const parser = new DOMParser(); const doc = parser.parseFromString(userInput, 'text/xml');

// ✅ Or disable external entities const options = { xmlMode: true, recognizeSelfClosing: true, decodeEntities: false, // Disable entity expansion };

  1. Broken Access Control 🚪

// ❌ No authorization check app.get('/api/user/:id', (req, res) => { const user = User.findById(req.params.id); res.json(user); // Anyone can see any user! });

// ✅ Proper authorization app.get('/api/user/:id', authenticate, (req, res) => { // Check if user can access this resource if (req.user.id !== req.params.id && !req.user.isAdmin) { return res.status(403).json({ error: 'Forbidden' }); }

const user = User.findById(req.params.id); res.json(user); });

// ✅ Role-based access control (RBAC) const authorize = roles => { return (req, res, next) => { if (!roles.includes(req.user.role)) { return res.status(403).json({ error: 'Insufficient permissions' }); } next(); }; };

app.delete('/api/users/:id', authenticate, authorize(['admin']), deleteUser);

  1. Security Misconfiguration ⚙️

✅ Security headers

app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], scriptSrc: ["'self'"], imgSrc: ["'self'", "data:", "https:"], }, }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true } }));

✅ Disable unnecessary features

app.disable('x-powered-by'); # Hide Express

✅ Error handling (don't leak info)

app.use((err, req, res, next) => { console.error(err.stack); // Log full error

// Send generic message to client res.status(500).json({ error: 'Internal server error', // Don't send: err.stack or err.message }); });

  1. Cross-Site Scripting (XSS) 🎭

// ❌ Vulnerable to XSS app.get('/search', (req, res) => { res.send(Results for: ${req.query.q}); // XSS! });

// ✅ Sanitize output const DOMPurify = require('isomorphic-dompurify');

app.get('/search', (req, res) => { const clean = DOMPurify.sanitize(req.query.q); res.send(Results for: ${clean}); });

// ✅ React automatically escapes <div>{userInput}</div> // Safe

// ❌ But dangerouslySetInnerHTML is dangerous <div dangerouslySetInnerHTML={{__html: userInput}} /> // XSS!

// ✅ Content-Type headers res.set('Content-Type', 'text/plain'); // Not HTML res.set('X-Content-Type-Options', 'nosniff');

  1. Insecure Deserialization 📦

// ❌ Dangerous deserialization const userData = JSON.parse(req.body.data); eval(userData.code); // Code execution!

// ✅ Validate before deserializing const schema = Joi.object({ name: Joi.string().required(), age: Joi.number().min(0).max(120), });

const { error, value } = schema.validate(JSON.parse(req.body.data)); if (error) return res.status(400).json({ error });

// ✅ Never deserialize untrusted data into code // Use JSON.parse() only, never eval() or Function()

  1. Components with Known Vulnerabilities 📚

✅ Regular dependency checks

Add to package.json

{ "scripts": { "security": "npm audit && npm outdated", "security:fix": "npm audit fix", "preinstall": "npm audit" } }

✅ Automated updates (GitHub)

.github/dependabot.yml

version: 2 updates:

  • package-ecosystem: "npm" directory: "/" schedule: interval: "daily" open-pull-requests-limit: 10
  1. Insufficient Logging & Monitoring 📊

// ✅ Comprehensive logging const winston = require('winston');

const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }), ], });

// ✅ Log security events function logSecurityEvent(event, user, details) { logger.warn({ type: 'SECURITY', event, user: user?.id, ip: user?.ip, timestamp: new Date().toISOString(), details, }); }

// Usage logSecurityEvent('FAILED_LOGIN', req.user, { attempts: failedAttempts, ip: req.ip, });

logSecurityEvent('UNAUTHORIZED_ACCESS', req.user, { resource: req.path, method: req.method, });

🔐 Password Security

// ✅ NEVER store plain text passwords! const bcrypt = require('bcrypt');

// Hashing async function hashPassword(password) { const saltRounds = 12; // Higher = more secure but slower return await bcrypt.hash(password, saltRounds); }

// Verifying async function verifyPassword(password, hash) { return await bcrypt.compare(password, hash); }

// ✅ Password reset flow async function resetPassword(email) { // 1. Generate secure token const token = crypto.randomBytes(32).toString('hex');

// 2. Store hashed token with expiry await storeResetToken(email, hashToken(token), Date.now() + 3600000);

// 3. Send unhashed token via email await sendEmail(email, Reset link: ${BASE_URL}/reset?token=${token}); }

🚪 API Security

// ✅ API Security Checklist const apiSecurity = { // 1. Authentication authentication: 'Bearer token (JWT)',

// 2. Rate limiting rateLimit: { windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // requests per window },

// 3. Input validation validateInput: (data, schema) => { return Joi.validate(data, schema); },

// 4. CORS configuration cors: { origin: process.env.ALLOWED_ORIGINS?.split(',') || false, credentials: true, },

// 5. API versioning versioning: '/api/v1/',

// 6. Request size limit bodyLimit: '10mb',

// 7. Timeout timeout: 30000, // 30 seconds

// 8. HTTPS only httpsOnly: true, };

📋 Security Deployment Checklist

Pre-Deployment Security Checklist

Code Security

  • No hardcoded secrets
  • All inputs validated
  • SQL queries parameterized
  • XSS protection enabled
  • CSRF tokens implemented
  • Authentication required
  • Authorization checks present
  • Rate limiting configured

Dependencies

  • npm audit shows 0 vulnerabilities
  • All packages from trusted sources
  • Lock file committed
  • Licenses reviewed

Configuration

  • Environment variables used
  • HTTPS enforced
  • Security headers set
  • CORS configured
  • Error messages sanitized
  • Debug mode disabled
  • Source maps disabled in production

Data Protection

  • Passwords hashed (bcrypt)
  • Sensitive data encrypted
  • PII fields marked
  • Data retention policy set
  • Backups encrypted

Infrastructure

  • Firewall rules configured
  • Ports minimized
  • SSH keys only (no passwords)
  • Monitoring enabled
  • Logging configured
  • Incident response plan ready

🚨 Incident Response Plan

// security-incident.js class SecurityIncident { async respond(incident) { // 1. Detect this.log('INCIDENT_DETECTED', incident);

// 2. Contain
await this.blockIP(incident.sourceIP);
await this.disableAccount(incident.userId);

// 3. Investigate
const logs = await this.gatherLogs(incident);

// 4. Remediate
await this.patchVulnerability(incident.vulnerability);

// 5. Recover
await this.restoreService();

// 6. Lessons Learned
await this.documentIncident(incident);

// 7. Notify
await this.notifyStakeholders(incident);

} }

💡 Security Quick Wins

1. Add security.txt

echo "Contact: security@example.com" > public/.well-known/security.txt

2. Enable Dependabot

gh api repos/:owner/:repo --method PUT --field security_and_analysis[secret_scanning][status]=enabled

3. Add pre-commit hooks

npm install --save-dev husky npx husky add .husky/pre-commit "npm audit"

4. Security headers test

curl -I https://yoursite.com | grep -i "strict-transport|content-security|x-frame"

Remember: Security is not a feature, it's a requirement! 🛡️

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

security-scanner

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

api-integration

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

dependency-doctor

No summary provided by upstream source.

Repository SourceNeeds Review