skills/second-order-injection-anti-pattern/SKILL.md
Security anti-pattern for second-order injection vulnerabilities (CWE-89 variant). Use when generating or reviewing code that retrieves data from databases, caches, or storage and uses it in subsequent queries or commands. Detects trusted internal data used unsafely.
npx skillsauth add igbuend/grimbard second-order-injection-anti-patternInstall 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.
Severity: High
Malicious payloads are stored safely in databases or logs, then executed later when retrieved and used without re-sanitization. Initial storage appears secure (properly parameterized), but subsequent retrieval and unsafe use activates the payload. Injection and execution points are separated in time and code location, making detection difficult.
The anti-pattern is treating database-retrieved data as safe and using it in queries or commands without re-sanitization or parameterization.
# VULNERABLE: Data is stored safely, but later retrieved and used unsafely.
import sqlite3
db = sqlite3.connect("app.db")
db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")
db.execute("CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY, action TEXT, user_email TEXT)")
# Step 1: User Registration (appears safe)
def register_user(name, email):
# Parameterized query, safe against direct injection.
# Attacker email: "[email protected]' UNION SELECT password FROM users -- "
# Safely stored as string in 'email' column.
db.execute("INSERT INTO users (name, email) VALUES (?, ?)", (name, email))
db.commit()
# Step 2: Logging (VULNERABLE on retrieval)
def log_user_action(user_id, action):
# Retrieve user email from database.
cursor = db.execute("SELECT email FROM users WHERE id = ?", (user_id,))
user_email = cursor.fetchone()[0]
# FLAW: user_email concatenated into query.
# Application "trusts" data from own database.
log_query = f"INSERT INTO logs (action, user_email) VALUES ('{action}', '{user_email}')"
# Result: INSERT INTO logs (action, user_email) VALUES ('view_profile', '[email protected]' UNION SELECT password FROM users -- ')
# Injected SQL executes, exposing passwords.
db.execute(log_query)
db.commit()
# Attack: Register with crafted email → trigger logging → payload executes.
# SECURE: All data used in SQL queries is parameterized, regardless of its source.
import sqlite3
db = sqlite3.connect("app_safe.db")
db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")
db.execute("CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY, action TEXT, user_email TEXT)")
# Step 1: User Registration (safe)
def register_user_safe(name, email):
db.execute("INSERT INTO users (name, email) VALUES (?, ?)", (name, email))
db.commit()
# Step 2: Logging (safe)
def log_user_action_safe(user_id, action):
cursor = db.execute("SELECT email FROM users WHERE id = ?", (user_id,))
user_email = cursor.fetchone()[0]
# SECURE: Database-retrieved user_email still treated as untrusted.
# Passed as parameter, not concatenated.
db.execute("INSERT INTO logs (action, user_email) VALUES (?, ?)", (action, user_email))
db.commit()
development
Security anti-pattern for Cross-Site Scripting vulnerabilities (CWE-79). Use when generating or reviewing code that renders HTML, handles user input in web pages, uses innerHTML/document.write, or builds dynamic web content. Covers Reflected, Stored, and DOM-based XSS. AI code has 86% XSS failure rate.
development
Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries.
development
Security anti-pattern for weak password hashing (CWE-327, CWE-759). Use when generating or reviewing code that stores or verifies user passwords. Detects use of MD5, SHA1, SHA256 without salt, or missing password hashing entirely. Recommends bcrypt, Argon2, or scrypt.
development
Security anti-pattern for weak encryption (CWE-326, CWE-327). Use when generating or reviewing code that encrypts data, handles encryption keys, or uses cryptographic modes. Detects DES, ECB mode, static IVs, and custom crypto implementations.