# Security Anti-Patterns # Patterns that may expose security vulnerabilities name: Security description: | Detects patterns that could lead to security vulnerabilities including missing authorization, data exposure, injection risks, and unsafe operations. Specific to Mantimon TCG patterns and FastAPI/Python conventions. patterns: - id: missing-auth-dependency description: Endpoint without authentication dependency grep_pattern: '@router\.(post|put|patch|delete)\([^)]*\)\n(async )?def \w+\([^)]*\):' multiline: true context_lines: 5 file_glob: 'app/api/**/*.py' verdict_hints: ISSUE_IF: "Mutating endpoint without get_current_user dependency" OK_IF: "Public endpoint (login, register, health) or has auth in deps" - id: password-in-log description: Password or secret potentially logged grep_pattern: 'logger\.\w+\(.*["\']?.*(password|secret|token|key|credential).*["\']?' context_lines: 2 verdict_hints: ISSUE_IF: "Sensitive value included in log message" OK_IF: "Just logging field name, not value; or intentionally masked" - id: sql-string-format description: SQL query built with string formatting (injection risk) grep_pattern: '(execute|text)\([^)]*(%|\.format|f["\'])' context_lines: 3 verdict_hints: ISSUE_IF: "User input could be interpolated into SQL" OK_IF: "Only constant values interpolated; user input uses params" - id: hidden-game-info-exposure description: Deck/hand contents potentially exposed to wrong player grep_pattern: '(deck|hand|prize).*\.(cards|contents|order)' context_lines: 5 file_glob: 'app/services/game_service.py' verdict_hints: ISSUE_IF: "Opponent's hidden zone contents sent to client" OK_IF: "Only counts sent, or filtered through visibility layer" - id: missing-ownership-check description: Resource access without verifying ownership grep_pattern: 'await.*(get_deck|get_collection|get_game).*\n(?!.*user_id|player_id)' multiline: true context_lines: 5 file_glob: 'app/api/**/*.py' verdict_hints: ISSUE_IF: "Resource fetched without checking user owns it" OK_IF: "Ownership check in service layer or resource is public" - id: hardcoded-secret description: Hardcoded secret or API key in code grep_pattern: '(api_key|secret|password|token)\s*=\s*["\'][^"\']{8,}["\']' context_lines: 2 exclude_tests: false verdict_hints: ISSUE_IF: "Real credential hardcoded in source" OK_IF: "Placeholder/example value; real value from environment" - id: debug-mode-check description: Debug mode check that might expose info in production grep_pattern: 'if.*(debug|DEBUG|dev_mode).*:\n.*print|logger' multiline: true context_lines: 4 verdict_hints: ISSUE_IF: "Sensitive data logged only when debug flag set" OK_IF: "Debug info is non-sensitive; flag properly controlled" - id: unsafe-pickle description: Pickle usage (arbitrary code execution risk) grep_pattern: 'pickle\.(load|loads)' context_lines: 3 verdict_hints: ISSUE_IF: "Unpickling data from untrusted source" OK_IF: "Never OK for external data; use JSON/msgpack instead" - id: eval-usage description: eval() or exec() usage grep_pattern: '(eval|exec)\s*\(' context_lines: 3 verdict_hints: ISSUE_IF: "Evaluating user-controlled input" OK_IF: "Extremely rare valid use; usually should refactor" - id: cors-wildcard description: CORS allowing all origins grep_pattern: 'allow_origins\s*=\s*\["\*"\]|allow_origin_regex.*\.\*' context_lines: 3 verdict_hints: ISSUE_IF: "Production API allows any origin" OK_IF: "Development only; production has specific origins"