skills/igbuend/grimbard/missing-input-validation-anti-pattern

missing-input-validation-anti-pattern

SKILL.md

Missing Input Validation Anti-Pattern

Severity: High

Summary

Missing input validation occurs when applications fail to validate data from users or external sources before processing it. This enables SQL Injection, Cross-Site Scripting (XSS), Command Injection, and Path Traversal attacks. Treat all incoming data as untrusted. Validate against strict rules for type, length, format, and range.

The Anti-Pattern

Trusting external input without server-side validation. Client-side validation provides no security—attackers bypass it trivially.

BAD Code Example

# VULNERABLE: Trusts user input completely, enabling SQL Injection
from flask import request
import sqlite3

@app.route("/api/products")
def search_products():
    # Takes 'category' directly from URL query string
    category = request.args.get("category")

    # Input concatenated directly into SQL query (classic SQL Injection)
    db = sqlite3.connect("database.db")
    cursor = db.cursor()
    query = f"SELECT id, name, price FROM products WHERE category = '{category}'"

    # Attacker request: /api/products?category=' OR 1=1 --
    # Resulting query: "SELECT ... FROM products WHERE category = '' OR 1=1 --'"
    # Returns ALL products, bypassing filter
    cursor.execute(query)
    products = cursor.fetchall()
    return {"products": products}

GOOD Code Example

# SECURE: Validates all input on server against strict allowlist
from flask import request
import sqlite3

# Strict allowlist of known-good values for 'category' parameter
ALLOWED_CATEGORIES = {"electronics", "books", "clothing", "homegoods"}

@app.route("/api/products/safe")
def search_products_safe():
    category = request.args.get("category")

    # 1. VALIDATE EXISTENCE: Check parameter provided
    if not category:
        return {"error": "Category parameter is required."}, 400

    # 2. VALIDATE AGAINST ALLOWLIST: Strongest form of input validation
    if category not in ALLOWED_CATEGORIES:
        return {"error": "Invalid category specified."}, 400

    # 3. USE PARAMETERIZED QUERIES: Safe database APIs prevent injection
    db = sqlite3.connect("database.db")
    cursor = db.cursor()
    # '?' placeholder treats input as data, not code
    query = "SELECT id, name, price FROM products WHERE category = ?"
    cursor.execute(query, (category,))
    products = cursor.fetchall()
    return {"products": products}

Detection

  • Trace user input: Follow HTTP request data (URL parameters, POST body, headers, cookies) through code. Verify validation occurs before use.
  • Find client-side-only validation: Check for required HTML attributes or JavaScript validation without server-side equivalents.
  • Identify missing checks: Find input handling without type, length, format, or range validation.

Prevention

Apply "Validate, then Act" to all incoming data.

  • Validate server-side: Client-side validation provides UX, not security
  • Use allowlists: Known-good lists beat known-bad blocklists
  • Apply multi-layer validation:
    • Type: Verify expected type (number vs string)
    • Length: Enforce min/max to prevent buffer overflows and DoS
    • Format: Match expected patterns (email, phone regex)
    • Range: Verify numerical bounds
  • Use schema validation libraries: For JSON/XML, use Pydantic, JSON Schema, or Marshmallow

Related Security Patterns & Anti-Patterns

Missing input validation enables most major vulnerability classes.

References

Weekly Installs
4
GitHub Stars
4
First Seen
Jan 20, 2026
Installed on
claude-code4
codex4
cursor4
opencode4
trae-cn3
gemini-cli3