All skills
jwynia avatar

/security-scan

@99a8797
by J Wyniajwynia/agent-skills160 stars
20

Scan code for security vulnerabilities including OWASP Top 10, secrets, and misconfigurations. Use when you need comprehensive security analysis of a codebase.

Use this Skill: https://skilld.dev/gh/jwynia/agent-skills/security-scan

This session only. Nothing lands on disk.

referencesremediationcommon-fixes.md

≈1.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Common Security Remediation Guide

Quick-reference fixes for common vulnerabilities.

Injection Prevention

SQL Injection

Use parameterized queries:

// Node.js (mysql2)
const [rows] = await conn.execute(
  'SELECT * FROM users WHERE id = ? AND status = ?',
  [userId, 'active']
);

// Node.js (pg)
const result = await client.query(
  'SELECT * FROM users WHERE id = $1',
  [userId]
);
# Python (psycopg2)
cursor.execute(
    "SELECT * FROM users WHERE id = %s AND status = %s",
    (user_id, 'active')
)

# Python (SQLAlchemy)
session.query(User).filter(User.id == user_id).first()

Command Injection

Avoid shell execution:

# VULNERABLE
os.system(f"ping {ip_address}")

# SECURE
import subprocess
subprocess.run(['ping', '-c', '1', ip_address], shell=False)
// VULNERABLE
exec(`ping ${ip}`);

// SECURE
const { spawn } = require('child_process');
spawn('ping', ['-c', '1', ip]);

XSS Prevention

Escape output:

// React (automatic escaping)
function Safe({ userInput }) {
  return <div>{userInput}</div>;
}

// Manual escaping
function escapeHtml(text) {
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

Cryptography Fixes

Password Hashing

Use bcrypt, Argon2, or scrypt:

// Node.js
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12);
const valid = await bcrypt.compare(password, hash);
# Python
import bcrypt
hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
valid = bcrypt.checkpw(password.encode(), hash)

Secure Random Generation

// Node.js
const crypto = require('crypto');
const token = crypto.randomBytes(32).toString('hex');
const uuid = crypto.randomUUID();
# Python
import secrets
token = secrets.token_hex(32)
safe_choice = secrets.choice(allowed_values)

Secure Encryption

// AES-256-GCM
const crypto = require('crypto');

function encrypt(text, key) {
  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return {
    iv: iv.toString('hex'),
    encrypted,
    tag: cipher.getAuthTag().toString('hex')
  };
}

Authentication Fixes

Strong Password Policy

const passwordPolicy = {
  minLength: 12,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSpecial: true
};

function validatePassword(password) {
  if (password.length < 12) return false;
  if (!/[A-Z]/.test(password)) return false;
  if (!/[a-z]/.test(password)) return false;
  if (!/[0-9]/.test(password)) return false;
  if (!/[!@#$%^&*]/.test(password)) return false;
  return true;
}

Secure Session Configuration

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

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);

Access Control Fixes

Authorization Middleware

function requireAuth(req, res, next) {
  if (!req.user) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  next();
}

function requireRole(...roles) {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ error: 'Forbidden' });
    }
    next();
  };
}

// Usage
app.get('/admin', requireAuth, requireRole('admin'), handler);

Resource Ownership Verification

async function getOrder(req, res) {
  const order = await Order.findOne({
    _id: req.params.id,
    userId: req.user.id  // Ownership check
  });

  if (!order) {
    return res.status(404).json({ error: 'Not found' });
  }

  res.json(order);
}

CORS Configuration

const cors = require('cors');

app.use(cors({
  origin: ['https://app.example.com'],
  methods: ['GET', 'POST'],
  credentials: true
}));

Path Traversal Fix

const path = require('path');

function safePath(basePath, userInput) {
  // Remove any path separators
  const filename = path.basename(userInput);
  const fullPath = path.resolve(basePath, filename);

  // Verify still within base
  if (!fullPath.startsWith(path.resolve(basePath))) {
    throw new Error('Invalid path');
  }

  return fullPath;
}

SSRF Prevention

const { URL } = require('url');

function isAllowedUrl(urlString) {
  try {
    const url = new URL(urlString);

    // Block internal networks
    const blockedPatterns = [
      /^localhost$/i,
      /^127\./,
      /^10\./,
      /^172\.(1[6-9]|2[0-9]|3[01])\./,
      /^192\.168\./,
      /^169\.254\./,
      /^0\.0\.0\.0$/
    ];

    for (const pattern of blockedPatterns) {
      if (pattern.test(url.hostname)) {
        return false;
      }
    }

    // Only allow HTTPS
    if (url.protocol !== 'https:') {
      return false;
    }

    return true;
  } catch {
    return false;
  }
}

Security Headers

const helmet = require('helmet');

app.use(helmet());

// Or configure individually:
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", "data:", "https:"],
  }
}));

app.use(helmet.hsts({
  maxAge: 31536000,
  includeSubDomains: true
}));

Input Validation

const Joi = require('joi');

const userSchema = Joi.object({
  email: Joi.string().email().required(),
  password: Joi.string().min(12).required(),
  age: Joi.number().integer().min(0).max(150)
});

function validateInput(req, res, next) {
  const { error } = userSchema.validate(req.body);
  if (error) {
    return res.status(400).json({ error: error.details[0].message });
  }
  next();
}

Secrets Management

// Use environment variables
const apiKey = process.env.API_KEY;
const dbPassword = process.env.DB_PASSWORD;

// Never commit secrets
// Use .env files for development only
// Use secrets manager in production (AWS Secrets Manager, Vault, etc.)

Example .env (add to .gitignore):

API_KEY=your-api-key
DB_PASSWORD=your-db-password

Quick Reference

Vulnerability Primary Fix
SQL Injection Parameterized queries
XSS Output encoding
Command Injection Avoid shell, use arrays
Weak Crypto bcrypt/Argon2, AES-GCM
Hardcoded Secrets Environment variables
SSRF URL allowlist
Path Traversal Validate paths
Missing Auth Middleware enforcement
Weak Sessions Secure cookie flags

Source: SKILL.md on GitHub

1 warning16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The security-scan skill is a comprehensive utility designed to guide an AI agent through the process of auditing codebases for security vulnerabilities. It provides structured detection patterns for OWASP Top 10 flaws, hardcoded secrets, and cryptographic weaknesses across various programming languages. The skill serves as a reference and instruction set for static analysis and does not contain any malicious code, unauthorized network operations, or persistence mechanisms.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    9/9 files flagged

Signed by skilld at 99a8797. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago
Other metadata
metadata
{
  "author": "jwynia",
  "version": "1.0",
  "type": "utility",
  "mode": "evaluative",
  "domain": "development"
}

README badge

README badge for jwynia/agent-skills/security-scan