home / skills / benchflow-ai / skillsbench / remediation-injection

This skill provides secure remediation patterns for SQL, command, and XSS injections with language-specific code examples.

npx playbooks add skill benchflow-ai/skillsbench --skill remediation-injection

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
8.7 KB
---
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**:
```python
# 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**:
```python
# 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**:
```javascript
// 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**:
```javascript
// 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**:
```java
// VULNERABLE: String concatenation
String query = "SELECT * FROM users WHERE id = '" + userId + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
```

**Do**:
```java
// 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**:
```go
// VULNERABLE: fmt.Sprintf in queries
query := fmt.Sprintf("SELECT * FROM users WHERE id = '%s'", userID)
rows, err := db.Query(query)
```

**Do**:
```go
// 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](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)

---

## Command Injection (CWE-78)

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

### Python

**Don't**:
```python
# 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**:
```python
# 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**:
```javascript
// 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**:
```javascript
// 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**:
```java
// VULNERABLE: Runtime.exec with concatenation
String cmd = "grep " + pattern + " " + filename;
Runtime.getRuntime().exec(cmd);
```

**Do**:
```java
// 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](https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html)

---

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

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

### JavaScript (DOM)

**Don't**:
```javascript
// VULNERABLE: innerHTML with user input
element.innerHTML = userInput;

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

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

**Do**:
```javascript
// 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**:
```jsx
// 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**:
```jsx
// 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**:
```python
# 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**:
```python
# 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](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html)

---

## Quick Reference

| Vulnerability | Fix Pattern | Key Libraries |
|---------------|-------------|---------------|
| SQL Injection | Parameterized queries | ORM, prepared statements |
| Command Injection | Argument arrays, no shell | subprocess, execFile |
| XSS | Auto-escaping, sanitization | DOMPurify, bleach |

## See Also

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

Overview

This skill provides actionable fix patterns for injection vulnerabilities (SQL, OS command, and XSS) with language-specific examples showing both vulnerable and secure implementations. It focuses on concrete code-level remediations to help developers convert unsafe patterns into safe ones. Use it to produce targeted remediation guidance and example fixes during code review or after an audit.

How this skill works

The skill inspects the type of injection risk and maps it to proven mitigation patterns: parameterized queries and ORM usage for SQL; argument arrays or avoiding shells for command execution; and auto-escaping plus sanitization for XSS. For each vulnerability class it supplies short, language-specific code snippets that illustrate the unsafe pattern and the secure replacement. It also calls out relevant libraries and standards (OWASP cheat sheets, ASVS mappings) to support recommendations.

When to use it

  • After finding SQL injection issues during an audit or pentest
  • When addressing OS command injection or unsafe subprocess usage
  • When fixing cross-site scripting (XSS) in UI or server-rendered templates
  • During code reviews to provide concrete remediation guidance
  • When converting quick prototypes that used string concatenation into production-safe code

Best practices

  • Prefer parameterized queries or ORM APIs over string concatenation for SQL
  • Avoid shell execution with user input; use argument arrays or dedicated libraries
  • Rely on framework auto-escaping and sanitize only when HTML must be allowed
  • Validate and normalize inputs but never treat validation as the sole defense
  • Use well-maintained libraries (DOMPurify, bleach, prepared statement APIs) and follow OWASP guidance

Example use cases

  • Replace concatenated SQL strings in a Python/psycopg2 codepath with parameterized queries
  • Refactor Node.js child_process.exec usage to execFile or spawn with argument arrays
  • Sanitize rich user-submitted HTML in a React app using DOMPurify before dangerouslySetInnerHTML
  • Convert Java Runtime.exec calls to ProcessBuilder with explicit argument lists
  • Update Go database queries to use parameter placeholders instead of fmt.Sprintf

FAQ

Does this skill detect vulnerabilities automatically?

No. It provides remediation patterns and examples; use a detection or scanning tool to find the issues first.

Can validation alone prevent injection?

Validation helps but is not sufficient. Combine validation with contextual defenses: parameterized queries, no-shell execution, and proper encoding/sanitization.