Files
leo-claude-mktplace/plugins/code-sentinel/skills/security-patterns/SKILL.md
lmiranda 870ed26510 feat: add code-sentinel plugin for security scanning and refactoring
Adds security scanning via PreToolUse hooks + refactoring commands:
- PreToolUse hook catches security issues before code is written
- /security-scan command for comprehensive security audit
- /refactor command to apply refactoring patterns
- /refactor-dry command to preview refactoring opportunities
- security-reviewer agent for vulnerability analysis
- refactor-advisor agent for code structure improvements
- security-patterns skill for vulnerability detection rules

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 12:32:43 -05:00

2.0 KiB

description
description
Security vulnerability patterns and detection rules

Security Patterns Skill

Critical Patterns (Always Block)

SQL Injection

# VULNERABLE
query = f"SELECT * FROM users WHERE id = {user_id}"
query = "SELECT * FROM users WHERE id = " + user_id

# SAFE
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
User.objects.filter(id=user_id)

Command Injection

# VULNERABLE
os.system(f"convert {filename} output.png")
subprocess.run(cmd, shell=True)

# SAFE
subprocess.run(["convert", filename, "output.png"], shell=False)
shlex.quote(filename)

Code Injection

# VULNERABLE
eval(user_input)
exec(user_code)

# SAFE
ast.literal_eval(user_input)  # Only for literals
# Use sandboxed execution environment

XSS

// VULNERABLE
element.innerHTML = userContent;
dangerouslySetInnerHTML={{__html: userData}}

// SAFE
element.textContent = userContent;
DOMPurify.sanitize(userContent)

Hardcoded Secrets

# VULNERABLE
API_KEY = "sk-1234567890abcdef"
password = "admin123"

# SAFE
API_KEY = os.environ.get("API_KEY")
password = get_secret("db_password")

Unsafe Deserialization

# VULNERABLE
data = pickle.loads(user_data)
config = yaml.load(file)  # yaml.load without Loader

# SAFE
data = json.loads(user_data)
config = yaml.safe_load(file)

Warning Patterns (Flag but Allow)

Broad Exception Handling

# WARNING
try:
    risky_operation()
except:
    pass

# BETTER
try:
    risky_operation()
except SpecificError as e:
    logger.error(f"Operation failed: {e}")
    raise

Missing Timeout

# WARNING
response = requests.get(url)

# BETTER
response = requests.get(url, timeout=30)

Path Traversal Risk

# WARNING
file_path = os.path.join(base_dir, user_filename)

# BETTER
file_path = os.path.join(base_dir, os.path.basename(user_filename))
if not file_path.startswith(os.path.abspath(base_dir)):
    raise ValueError("Invalid path")