Marketplace

remediation-injection

Security fix patterns for injection vulnerabilities (SQL, Command, XSS). Provides language-specific code examples showing vulnerable and secure implementations.

$ Installer

git clone https://github.com/Zate/cc-plugins /tmp/cc-plugins && cp -r /tmp/cc-plugins/plugins/security/skills/remediation-injection ~/.claude/skills/cc-plugins

// tip: Run this command in your terminal to install the skill


name: remediation-injection description: Security fix patterns for injection vulnerabilities (SQL, Command, XSS). Provides language-specific code examples showing vulnerable and secure implementations.

Remediation: Injection Vulnerabilities

Actionable fix patterns for injection-based security vulnerabilities.

When to Use This Skill

  • Fixing SQL injection - After finding SQL injection in audits
  • Fixing command injection - After finding OS command injection
  • Fixing XSS - After finding cross-site scripting vulnerabilities
  • Code review feedback - Provide remediation guidance with examples

When NOT to Use This Skill

  • Detecting vulnerabilities - Use vulnerability-patterns skill
  • Fixing crypto issues - Use remediation-crypto skill
  • Fixing auth issues - Use remediation-auth skill
  • Fixing config issues - Use remediation-config skill

SQL Injection (CWE-89)

Problem

User input directly concatenated into SQL queries allows attackers to manipulate database queries.

Python (SQLAlchemy/psycopg2)

Don't:

# VULNERABLE: String concatenation
def get_user_bad(user_id):
    query = f"SELECT * FROM users WHERE id = '{user_id}'"
    cursor.execute(query)
    return cursor.fetchone()

# VULNERABLE: Format strings
query = "SELECT * FROM users WHERE name = '%s'" % username

Do:

# SECURE: Parameterized queries with psycopg2
def get_user_safe(user_id):
    query = "SELECT * FROM users WHERE id = %s"
    cursor.execute(query, (user_id,))
    return cursor.fetchone()

# SECURE: SQLAlchemy ORM
def get_user_orm(user_id):
    return db.session.query(User).filter(User.id == user_id).first()

# SECURE: SQLAlchemy with text() and bindparams
from sqlalchemy import text
query = text("SELECT * FROM users WHERE id = :user_id")
result = db.session.execute(query, {"user_id": user_id})

JavaScript/TypeScript (Node.js)

Don't:

// VULNERABLE: String concatenation
const query = `SELECT * FROM users WHERE id = '${userId}'`;
db.query(query);

// VULNERABLE: Template literals
const sql = `SELECT * FROM products WHERE name LIKE '%${searchTerm}%'`;

Do:

// SECURE: Parameterized queries (mysql2)
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);

// SECURE: Parameterized with named placeholders (pg)
const query = 'SELECT * FROM users WHERE id = $1';
await client.query(query, [userId]);

// SECURE: Prisma ORM
const user = await prisma.user.findUnique({
  where: { id: userId }
});

// SECURE: Knex.js query builder
const user = await knex('users').where('id', userId).first();

Java (JDBC)

Don't:

// VULNERABLE: String concatenation
String query = "SELECT * FROM users WHERE id = '" + userId + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);

Do:

// SECURE: PreparedStatement
String query = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1, userId);
ResultSet rs = pstmt.executeQuery();

// SECURE: JPA/Hibernate with named parameters
@Query("SELECT u FROM User u WHERE u.id = :userId")
User findByUserId(@Param("userId") String userId);

Go

Don't:

// VULNERABLE: fmt.Sprintf in queries
query := fmt.Sprintf("SELECT * FROM users WHERE id = '%s'", userID)
rows, err := db.Query(query)

Do:

// SECURE: Parameterized queries
query := "SELECT * FROM users WHERE id = $1"
rows, err := db.Query(query, userID)

// SECURE: With sqlx
var user User
err := db.Get(&user, "SELECT * FROM users WHERE id = $1", userID)

ASVS: V1.2.1, V1.2.2 References: OWASP SQL Injection Prevention


Command Injection (CWE-78)

Problem

User input passed to shell commands allows attackers to execute arbitrary system commands.

Python

Don't:

# VULNERABLE: shell=True with user input
import subprocess
subprocess.run(f"grep {pattern} {filename}", shell=True)

# VULNERABLE: os.system
import os
os.system(f"convert {input_file} {output_file}")

Do:

# SECURE: subprocess with argument list (no shell)
import subprocess
import shlex

result = subprocess.run(
    ['grep', pattern, filename],
    capture_output=True,
    text=True
)

# SECURE: If shell is required, use shlex.quote
if shell_required:
    safe_filename = shlex.quote(filename)
    subprocess.run(f"process {safe_filename}", shell=True)

# SECURE: Use libraries instead of shell commands
from PIL import Image
img = Image.open(input_file)
img.save(output_file)

JavaScript/Node.js

Don't:

// VULNERABLE: exec with user input
const { exec } = require('child_process');
exec(`grep ${pattern} ${filename}`);

// VULNERABLE: String interpolation in shell command
exec(`convert ${inputFile} ${outputFile}`);

Do:

// SECURE: execFile with argument array
const { execFile } = require('child_process');
execFile('grep', [pattern, filename], (error, stdout) => {
  console.log(stdout);
});

// SECURE: spawn with arguments
const { spawn } = require('child_process');
const grep = spawn('grep', [pattern, filename]);

// SECURE: Use libraries instead of shell commands
const sharp = require('sharp');
await sharp(inputFile).toFile(outputFile);

Java

Don't:

// VULNERABLE: Runtime.exec with concatenation
String cmd = "grep " + pattern + " " + filename;
Runtime.getRuntime().exec(cmd);

Do:

// SECURE: ProcessBuilder with argument list
ProcessBuilder pb = new ProcessBuilder("grep", pattern, filename);
pb.redirectErrorStream(true);
Process process = pb.start();

ASVS: V1.2.3 References: OWASP OS Command Injection


Cross-Site Scripting (XSS) (CWE-79)

Problem

User input rendered in HTML without proper encoding allows script injection.

JavaScript (DOM)

Don't:

// VULNERABLE: innerHTML with user input
element.innerHTML = userInput;

// VULNERABLE: document.write
document.write(userData);

// VULNERABLE: jQuery html()
$('#content').html(userInput);

Do:

// SECURE: textContent for plain text
element.textContent = userInput;

// SECURE: DOMPurify for HTML content
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userHtml);

// SECURE: Create elements programmatically
const link = document.createElement('a');
link.href = sanitizeUrl(userUrl);
link.textContent = userText;
parent.appendChild(link);

// SECURE: jQuery text()
$('#content').text(userInput);

React

Don't:

// VULNERABLE: dangerouslySetInnerHTML without sanitization
function Comment({ content }) {
  return <div dangerouslySetInnerHTML={{ __html: content }} />;
}

// VULNERABLE: href with user input (javascript: URLs)
<a href={userUrl}>Click here</a>

Do:

// SECURE: React auto-escapes by default
function Comment({ content }) {
  return <div>{content}</div>;
}

// SECURE: Sanitize if HTML is required
import DOMPurify from 'dompurify';
function RichContent({ html }) {
  const clean = DOMPurify.sanitize(html);
  return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}

// SECURE: Validate URLs
function SafeLink({ url, text }) {
  const isValid = /^https?:\/\//.test(url);
  if (!isValid) return <span>{text}</span>;
  return <a href={url}>{text}</a>;
}

Python (Flask/Jinja2)

Don't:

# VULNERABLE: Marking as safe without sanitization
from markupsafe import Markup
return Markup(f"<div>{user_input}</div>")

# VULNERABLE: Disabling autoescaping
{% autoescape false %}
  {{ user_content }}
{% endautoescape %}

Do:

# SECURE: Let Jinja2 auto-escape (default)
return render_template('page.html', content=user_input)

# Template: auto-escaped by default
<div>{{ content }}</div>

# SECURE: Use bleach for allowing specific HTML
import bleach
allowed_tags = ['b', 'i', 'u', 'a']
allowed_attrs = {'a': ['href']}
clean = bleach.clean(user_html, tags=allowed_tags, attributes=allowed_attrs)

ASVS: V3.3.1, V1.3.1 References: OWASP XSS Prevention


Quick Reference

VulnerabilityFix PatternKey Libraries
SQL InjectionParameterized queriesORM, prepared statements
Command InjectionArgument arrays, no shellsubprocess, execFile
XSSAuto-escaping, sanitizationDOMPurify, bleach

See Also

  • remediation-crypto - Cryptography fixes
  • remediation-auth - Authentication/authorization fixes
  • remediation-config - Configuration fixes
  • vulnerability-patterns - Detection patterns