Prevents RCE, SQL injection, and common vulnerabilities through validation and safe coding practices. Use when implementing or reviewing security-sensitive code involving user input, database queries, or command execution.
Prevents RCE, SQL injection, and common vulnerabilities through validation and safe coding practices. Use when implementing or reviewing security-sensitive code involving user input, database queries, or command execution.
/plugin marketplace add binee108/nine-step-workflow-plugin/plugin install nine-step-workflow@lilylab-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
NEVER:
eval(), exec() with user input (RCE risk)os.system(), subprocess with shell=True and user inputALWAYS:
# ❌ DANGEROUS
eval(request.json['code']) # RCE!
query = f"SELECT * FROM users WHERE id = '{user_id}'" # SQL injection!
# ✅ SAFE
ALLOWED = {'add': lambda a,b: a+b}
if op in ALLOWED:
result = ALLOWED[op](a, b)
query = "SELECT * FROM users WHERE id = %s"
db.execute(query, (user_id,))
// ❌ DANGEROUS
eval(req.body.code); // RCE!
const query = `SELECT * FROM users WHERE id = '${userId}'`; // SQL injection!
// ✅ SAFE
const ALLOWED = {add: (a,b) => a+b};
if (ALLOWED[op]) {
result = ALLOWED[op](a, b);
}
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);
// ❌ DANGEROUS
cmd := exec.Command("sh", "-c", userInput) // RCE!
query := fmt.Sprintf("SELECT * FROM users WHERE id = '%s'", userId) // SQL injection!
// ✅ SAFE
var allowed = map[string]func(int, int) int{
"add": func(a, b int) int { return a + b },
}
if fn, ok := allowed[op]; ok {
result = fn(a, b)
}
query := "SELECT * FROM users WHERE id = ?"
db.Query(query, userId)
Vulnerable:
# SQL Injection
query = "SELECT * FROM users WHERE name = '" + userName + "'"
# Command Injection
os.system("ping " + userIP)
# NoSQL Injection
db.find({"user": req.body.user}) # MongoDB
Secure:
# Parameterized SQL
query = "SELECT * FROM users WHERE name = ?"
db.execute(query, [userName])
# Allowlist validation + safe execution
if re.match(r'^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$', userIP):
subprocess.run(["ping", "-c", "1", userIP], shell=False)
# Strict schema validation
if (typeof req.body.user === 'string') {
db.find({user: req.body.user})
}
Vulnerable:
# Weak password storage
password = hashlib.md5(password).hexdigest() # MD5 broken!
# No rate limiting
if user.password == input_password: # Brute force vulnerability
Secure:
# Strong hashing
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
# Rate limiting
from flask_limiter import Limiter
@limiter.limit("5 per minute")
def login():
...
Vulnerable:
# Plaintext secrets in code
API_KEY = "sk_live_abc123xyz" # Hardcoded!
# Logging sensitive data
logger.info(f"User password: {password}") # Password in logs!
Secure:
# Environment variables
import os
API_KEY = os.getenv('API_KEY')
# Masked logging
logger.info(f"User: {username}, Password: [REDACTED]")
Vulnerable:
# Python lxml (unsafe)
parser = etree.XMLParser()
doc = etree.parse(user_file, parser)
# Java (unsafe)
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
Secure:
# Python (safe)
parser = etree.XMLParser(resolve_entities=False, no_network=True)
doc = etree.parse(user_file, parser)
# Java (safe)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
Vulnerable:
# No authorization check
@app.route('/admin/users')
def admin_users():
return User.query.all() # Anyone can access!
# IDOR (Insecure Direct Object Reference)
@app.route('/user/<id>')
def get_user(id):
return User.query.get(id) # No ownership check!
Secure:
# Role-based access control
@app.route('/admin/users')
@require_role('admin')
def admin_users():
return User.query.all()
# Verify ownership
@app.route('/user/<id>')
def get_user(id):
user = User.query.get(id)
if user.id != current_user.id and not current_user.is_admin:
abort(403)
return user
Vulnerable:
# Debug mode in production
app.run(debug=True) # Exposes stack traces!
# Default credentials
DB_PASSWORD = "admin123" # Weak default!
Secure:
# Production configuration
app.run(debug=False, host='0.0.0.0')
# Strong credentials from environment
DB_PASSWORD = os.getenv('DB_PASSWORD')
if not DB_PASSWORD:
raise ValueError("DB_PASSWORD must be set")
Vulnerable:
# Unescaped output (Python/Flask)
return f"<h1>Hello {user_name}</h1>" # user_name = "<script>alert('XSS')</script>"
# Unsafe HTML (JavaScript)
div.innerHTML = userName; # XSS!
Secure:
# Auto-escaping (Flask Jinja2)
return render_template('hello.html', name=user_name)
# Template: <h1>Hello {{ name }}</h1> (auto-escaped)
# Text content only (JavaScript)
div.textContent = userName; // Safe
# Or sanitize HTML
import DOMPurify from 'dompurify';
div.innerHTML = DOMPurify.sanitize(userHTML);
Vulnerable:
# Python pickle (unsafe)
import pickle
data = pickle.loads(user_input) # RCE!
# YAML (unsafe)
import yaml
config = yaml.load(user_file) # RCE!
Secure:
# JSON only
import json
data = json.loads(user_input) # Safe (no code execution)
# Safe YAML
config = yaml.safe_load(user_file) # Restricted types
Vulnerable:
# Outdated dependencies
requests==2.6.0 # Has CVE-2015-2296!
Secure:
# Regular updates
pip install --upgrade requests
# Vulnerability scanning
pip install safety
safety check
# Or npm
npm audit
npm audit fix
Vulnerable:
# No security event logging
if auth_failed:
return "Invalid credentials" # Silent failure
Secure:
# Log security events
if auth_failed:
logger.warning(f"Failed login for user: {username}, IP: {request.remote_addr}")
# Alert after N failures
if failed_attempts > 5:
alert_security_team(username, request.remote_addr)
return "Invalid credentials"
[ ] No eval/exec with user input?
[ ] SQL queries parameterized?
[ ] File paths validated?
[ ] All inputs validated?
[ ] Passwords hashed (bcrypt/argon2)?
[ ] Secrets in environment variables?
[ ] Authentication with rate limiting?
[ ] Authorization checks on all endpoints?
[ ] XSS prevention (auto-escaping)?
[ ] Deserialization uses safe formats (JSON)?
[ ] Dependencies regularly updated?
[ ] Security events logged?
# ✅ Safe file upload
from werkzeug.utils import secure_filename
# Validate extension
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
if not file.filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS:
abort(400)
# Secure filename
filename = secure_filename(file.filename)
# Limit file size
if len(file.read()) > 5 * 1024 * 1024: # 5MB
abort(400)
# Store outside web root
file.save(os.path.join('/var/uploads', filename))
# Flask-WTF (automatic CSRF)
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
# Or manual token validation
if request.form['csrf_token'] != session['csrf_token']:
abort(403)
# Force HTTPS (Flask)
from flask_talisman import Talisman
Talisman(app, force_https=True)
# Secure cookies
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
For detailed guidelines, see reference.md For more examples, see examples.md
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.