Skip to main content
This page documents product operation incidents in the ShopStack Python service, with a focus on security vulnerabilities, particularly SQL injection attacks.

Overview

Product operations issues can expose critical security vulnerabilities, compromise data integrity, and impact search functionality. The most severe issues include:
  • SQL injection vulnerabilities
  • Unsafe query construction
  • Search functionality bugs
  • Input validation failures

Incidents

Common Patterns

Safe Query Construction

from sqlalchemy import or_, and_
from app.models.product import Product

# SAFE: Using ORM
def search_products_safe(search_term, category=None, min_price=None, max_price=None):
    """Safe product search using SQLAlchemy ORM."""
    query = Product.query
    
    # Text search
    if search_term:
        search_pattern = f"%{search_term}%"
        query = query.filter(
            or_(
                Product.name.ilike(search_pattern),
                Product.description.ilike(search_pattern)
            )
        )
    
    # Category filter
    if category:
        query = query.filter(Product.category == category)
    
    # Price range
    if min_price is not None:
        query = query.filter(Product.price >= min_price)
    if max_price is not None:
        query = query.filter(Product.price <= max_price)
    
    return query.all()

# UNSAFE: Never do this
def search_products_unsafe(search_term):
    """DANGEROUS: SQL injection vulnerability!"""
    sql = f"SELECT * FROM products WHERE name LIKE '%{search_term}%'"  # NEVER!
    return db.session.execute(db.text(sql))

Parameterized Raw SQL (When Necessary)

from sqlalchemy import text

def complex_product_query(search_term, min_rating):
    """Example of safe raw SQL with parameters."""
    sql = text("""
        SELECT p.*, AVG(r.rating) as avg_rating
        FROM products p
        LEFT JOIN reviews r ON p.id = r.product_id
        WHERE (p.name ILIKE :search OR p.description ILIKE :search)
        GROUP BY p.id
        HAVING AVG(r.rating) >= :min_rating
        ORDER BY avg_rating DESC
    """)
    
    # Safe: Parameters are properly escaped
    results = db.session.execute(sql, {
        "search": f"%{search_term}%",
        "min_rating": min_rating
    })
    
    return results.fetchall()

Input Validation Decorator

from functools import wraps
import re
from flask import request, jsonify

def validate_search_input(max_length=100):
    """Decorator to validate search input."""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            query = request.args.get('q', '')
            
            # Length check
            if len(query) > max_length:
                return jsonify({"error": "Search query too long"}), 400
            
            # Pattern check (defense in depth)
            forbidden = [r'\bUNION\b', r'\bSELECT\b', r'--', r'/\*']
            for pattern in forbidden:
                if re.search(pattern, query, re.IGNORECASE):
                    return jsonify({"error": "Invalid search query"}), 400
            
            return f(*args, **kwargs)
        return decorated_function
    return decorator

@products_bp.route("/search", methods=["GET"])
@validate_search_input(max_length=100)
def search_products():
    query = request.args.get("q", "")
    # ... safe search implementation ...

Security Checklist

Code Review Checklist

  • No string interpolation (f"SELECT ... {var}") in SQL queries
  • No .format() used with SQL queries
  • All raw SQL uses parameterized queries (:param syntax)
  • ORM used when possible instead of raw SQL
  • Input validation on all user-provided data
  • No sensitive data in error messages
  • Rate limiting on search endpoints
  • Database user has minimal required permissions

Testing Checklist

  • Test SQL injection with ' OR '1'='1
  • Test UNION attacks
  • Test comment-based attacks (--, /**/)
  • Test special characters in search terms
  • Test excessively long input
  • Verify error messages don’t leak SQL structure

Deployment Checklist

  • Static analysis tools (bandit) in CI pipeline
  • Regular penetration testing scheduled
  • Security headers configured (CSP, X-Frame-Options, etc.)
  • Database connection uses least-privilege user
  • Logging of suspicious query patterns
  • Rate limiting enabled

Quick Reference

VulnerabilityAttack ExamplePrevention
SQL Injection' OR '1'='1Use ORM or parameterized queries
UNION Attack' UNION SELECT ...Never interpolate user input in SQL
Comment Injectiontest'--Input validation + parameterized queries
Blind SQL Injection' AND SLEEP(5)--Use ORM, monitor slow queries

Tools & Resources

Security Scanning Tools

# Bandit - Python security scanner
pip install bandit
bandit -r app/ -ll  # Show medium and high severity issues

# SQLMap - SQL injection testing tool
sqlmap -u "http://localhost:5000/api/products/search?q=test" --batch

# Safety - Check dependencies for known vulnerabilities
pip install safety
safety check --json
  • SQLAlchemy: ORM with built-in SQL injection protection
  • Flask-Limiter: Rate limiting to prevent abuse
  • Flask-Talisman: Security headers for Flask apps
  • python-decouple: Secure configuration management

See Also

Build docs developers (and LLMs) love