skills/security/owasp-guardian/injection-prevention/SKILL.md
OWASP A01 - Injection Prevention. Use this skill when reviewing code for SQL injection, NoSQL injection, command injection, LDAP injection, or any user input that reaches databases, shells, or interpreters. Activate when: SQL query, database query, user input, command execution, shell command, exec, eval, system call, parameterized query.
npx skillsauth add latestaiagents/agent-skills injection-preventionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Prevent SQL, NoSQL, Command, and other injection attacks by validating and sanitizing all user input.
| Type | Danger | Common Locations | |------|--------|------------------| | SQL Injection | CRITICAL | Database queries, ORMs with raw queries | | NoSQL Injection | CRITICAL | MongoDB, Redis, Elasticsearch queries | | Command Injection | CRITICAL | Shell exec, system calls, child_process | | LDAP Injection | HIGH | Directory service queries | | XPath Injection | HIGH | XML document queries | | Expression Language | HIGH | Template engines, eval() |
// VULNERABLE - String concatenation
const query = "SELECT * FROM users WHERE id = " + userId;
const query = `SELECT * FROM users WHERE name = '${userName}'`;
// VULNERABLE - Format strings
query = "SELECT * FROM users WHERE id = %s" % user_id
// VULNERABLE - String interpolation in ORM
User.where("name = '#{params[:name]}'")
// VULNERABLE - Direct user input in commands
exec(`ls ${userInput}`);
system("ping " + ipAddress);
child_process.exec(`convert ${filename} output.png`);
// VULNERABLE - eval with user data
eval(userCode);
new Function(userInput)();
// SAFE - Node.js with parameterized query
const result = await db.query(
'SELECT * FROM users WHERE id = $1 AND status = $2',
[userId, status]
);
// SAFE - Using ORM properly
const user = await User.findOne({ where: { id: userId } });
// SAFE - Prepared statements
const stmt = db.prepare('SELECT * FROM users WHERE email = ?');
const user = stmt.get(email);
# SAFE - Python with parameterized query
cursor.execute(
"SELECT * FROM users WHERE id = %s AND status = %s",
(user_id, status)
)
# SAFE - SQLAlchemy ORM
user = session.query(User).filter(User.id == user_id).first()
// SAFE - PHP PDO with prepared statements
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $userId]);
// VULNERABLE - MongoDB with user object
db.users.find({ username: req.body.username, password: req.body.password });
// Attack: { "username": "admin", "password": { "$ne": "" } }
// SAFE - Validate and sanitize input
const username = String(req.body.username).slice(0, 50);
const password = String(req.body.password);
// SAFE - Use mongoose with schema validation
const userSchema = new Schema({
username: { type: String, required: true, maxlength: 50 },
password: { type: String, required: true }
});
// VULNERABLE
exec(`convert ${filename} output.png`);
// SAFE - Use array arguments (no shell)
execFile('convert', [filename, 'output.png']);
// SAFE - Whitelist allowed values
const ALLOWED_FORMATS = ['png', 'jpg', 'gif'];
if (!ALLOWED_FORMATS.includes(format)) {
throw new Error('Invalid format');
}
// SAFE - Use library instead of shell
const sharp = require('sharp');
await sharp(inputFile).toFile(outputFile);
# VULNERABLE
os.system(f"ping {ip_address}")
# SAFE - Use subprocess with list arguments
import subprocess
subprocess.run(['ping', '-c', '4', ip_address], check=True)
# SAFE - Use library instead of shell
import socket
socket.gethostbyname(hostname)
// Validation helper
function validateInput(input, options = {}) {
const { maxLength = 255, pattern, allowedValues } = options;
// Type check
if (typeof input !== 'string') {
throw new ValidationError('Input must be a string');
}
// Length check
if (input.length > maxLength) {
throw new ValidationError(`Input exceeds ${maxLength} characters`);
}
// Pattern check
if (pattern && !pattern.test(input)) {
throw new ValidationError('Input contains invalid characters');
}
// Whitelist check
if (allowedValues && !allowedValues.includes(input)) {
throw new ValidationError('Input value not allowed');
}
return input;
}
// Usage
const userId = validateInput(req.params.id, {
maxLength: 36,
pattern: /^[a-f0-9-]+$/i // UUID pattern
});
# SQL Injection tests
' OR '1'='1
'; DROP TABLE users; --
' UNION SELECT * FROM passwords --
1; SELECT * FROM users
# NoSQL Injection tests
{"$gt": ""}
{"$ne": null}
{"$where": "sleep(5000)"}
# Command Injection tests
; ls -la
| cat /etc/passwd
`whoami`
$(id)
# SQLMap for SQL injection
sqlmap -u "http://target.com/page?id=1" --dbs
# NoSQLMap for NoSQL injection
nosqlmap -u "http://target.com/api/users"
# Commix for command injection
commix -u "http://target.com/ping?ip=127.0.0.1"
express-validator for input validationeval() or child_process.exec() with user inputsubprocess.run() with list argumentsSECURE_CONTENT_TYPE_NOSNIFFwhere("column = '#{value}'")Shellwords.escape() for shell argumentsescapeshellarg() for shell argumentsdevelopment
Test skills for correct activation, content quality, and regression — both automated checks (frontmatter validity, lint) and manual verification (query-suite activation testing). Covers CI integration and how to catch skill regressions before users do. Use this skill when adding skills to a repo, setting up CI for a skill library, or debugging "the skill exists but doesn't work". Activate when: test skills, validate skills, skill CI, skill linting, skill activation test, skill regression.
documentation
Write the YAML frontmatter for a SKILL.md file so it activates reliably — name, description, and activation keywords that the model matches against. Covers length, tone, and the most common frontmatter mistakes. Use this skill when authoring a new skill, fixing a skill that isn't auto-activating, or reviewing skills for publication. Activate when: SKILL.md frontmatter, skill description, skill activation, skill YAML, write a skill, author a skill.
development
Design skills that fire at the right moment — neither over-eager (noise) nor under-eager (silent). Covers activation specificity, trigger phrases, disambiguation between overlapping skills, and debugging activation. Use this skill when multiple skills could fire on the same query, a skill never fires, or a skill fires too often. Activate when: skill won't activate, skill over-activates, overlapping skills, skill triggers, skill selection, skill disambiguation.
development
Structure SKILL.md content so the model reads just enough — concise summary up front, progressively deeper detail, examples on demand. Covers section ordering, length budgets, when to split into multiple skills. Use this skill when writing or refactoring a skill body, one skill has grown too long, or a skill is wordy but not useful. Activate when: SKILL.md structure, skill content, skill too long, split skill, progressive disclosure, skill body.