rules:
  - id: auth.java.crypto.weak-password-hash
    languages:
      - java
    severity: ERROR
    message: |
      A password is being hashed with a fast, general-purpose digest from the
      JCA `MessageDigest` (MD5, SHA-1, SHA-256, SHA-512). These algorithms are
      designed to be fast, which makes offline brute-force and rainbow-table
      attacks cheap. They are NOT suitable for storing passwords (CWE-916).

      Use a dedicated, slow password-hashing function with a per-password salt
      and a tunable work factor: BCrypt (`BCryptPasswordEncoder`), Argon2
      (`Argon2PasswordEncoder`), or PBKDF2 (`Pbkdf2PasswordEncoder` /
      `SecretKeyFactory` with `PBKDF2WithHmacSHA256`). These resist brute-force
      by design.
    # Anchored to the *password* character of the input: the digested/updated
    # argument must be named like a password (metavariable-regex on $PW), and a
    # weak MessageDigest must be instantiated in the same enclosing method
    # (pattern-inside). This avoids flagging `MessageDigest.getInstance("SHA-256")`
    # used for file checksums or non-password fingerprints, and does not touch
    # real password hashers (BCrypt/Argon2/PBKDF2).
    patterns:
      - pattern-either:
          - pattern: $MD.digest($PW.getBytes(...))
          - pattern: $MD.digest($PW)
          - pattern: $MD.update($PW.getBytes(...))
          - pattern: $MD.update($PW)
      - metavariable-regex:
          metavariable: $PW
          regex: (?i).*(password|passwd|pwd).*
      - pattern-inside: |
          MessageDigest $MD = MessageDigest.getInstance("=~/(?i)^(MD5|SHA-?1|SHA-?256|SHA-?512)$/");
          ...
    metadata:
      oauthlint-rule-id: AUTH-JAVA-CRYPTO-001
      oauthlint-doc-url: https://oauthlint.dev/rules/java-crypto-weak-password-hash
      category: security
      cwe: CWE-916
      owasp: A02:2021
      llm-prevalence: HIGH
      technology:
        - java.security
      references:
        - https://cwe.mitre.org/data/definitions/916.html
        - https://docs.spring.io/spring-security/reference/features/authentication/password-storage.html
        - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
