# 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"
