# PHP security rules (Tier 1 regex).

- id: php-md5-deprecated
  name: md5() used for security purposes
  pattern: '\bmd5\s*\('
  message: "md5() is broken for security — use password_hash() or hash('sha256', ...)"
  severity: medium
  category: security
  languages: [php]
  cwe: CWE-327
  confidence: 0.6
  recommendation: "Use password_hash($pw, PASSWORD_BCRYPT) for passwords, hash('sha256', ...) for general hashing."

- id: php-mysql-real-escape-string-only
  name: mysql_real_escape_string as sole defense
  pattern: '\bmysql_real_escape_string\s*\('
  message: "mysql_* extension is removed in PHP 7+ — use PDO with parameterized queries"
  severity: high
  category: security
  languages: [php]
  cwe: CWE-89
  confidence: 0.85
  recommendation: "Migrate to PDO::prepare with bindParam, or mysqli prepared statements."

- id: php-superglobal-direct-output
  name: $_GET / $_POST echoed directly
  pattern: 'echo\s+\$_(?:GET|POST|REQUEST|COOKIE)'
  message: "Echoing user input directly — XSS risk; escape with htmlspecialchars()"
  severity: high
  category: security
  languages: [php]
  cwe: CWE-79
  confidence: 0.8
  recommendation: "Wrap in htmlspecialchars($value, ENT_QUOTES, 'UTF-8') before echoing."

- id: php-include-variable
  name: include with a variable path
  pattern: '\b(?:include|require)(?:_once)?\s*\(\s*\$'
  message: "include/require with variable path — risk of LFI/RFI if attacker controls the path"
  severity: high
  category: security
  languages: [php]
  cwe: CWE-98
  confidence: 0.6
  recommendation: "Whitelist allowed paths, or build the path from an allowlist of identifiers."

- id: php-error-reporting-display
  name: display_errors enabled
  pattern: "display_errors[^=]*=\\s*['\"]?(?:1|on|true)"
  message: "display_errors leaks stack traces and paths to users in production"
  severity: medium
  category: security
  languages: [php]
  cwe: CWE-209
  confidence: 0.7
  recommendation: "Set display_errors = Off in production; log errors to a file instead."

- id: php-suppress-error
  name: Error suppression operator
  pattern: '@\w'
  message: "@ suppresses errors silently — fix the underlying issue or handle it explicitly"
  severity: low
  category: suspicious
  languages: [php]
  confidence: 0.5
  recommendation: "Use try/catch or check the precondition; @ hides bugs."
