rules:
  - id: python-use-of-des
    patterns:
      - pattern-either:
          - pattern: cryptography.hazmat.primitives.ciphers.algorithms.TripleDES(...)
          - pattern: Crypto.Cipher.DES.new(...)
          - pattern: Crypto.Cipher.DES3.new(...)
          - pattern: Cryptodome.Cipher.DES.new(...)
          - pattern: Cryptodome.Cipher.DES3.new(...)
    message: >-
      DES has a 56-bit key -- completely broken classically and trivially quantum-vulnerable. Migrate to
      AES-256-GCM.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
        - post-quantum
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: CRITICAL
      quantum_vulnerable: true
      quantum_attack: "Grover's Algorithm"
      quantum_risk_score: 10
      post_quantum_alternatives:
        - "AES-256"
      references:
        - https://csrc.nist.gov/projects/post-quantum-cryptography

  - id: python-use-of-3des
    patterns:
      - pattern-either:
          - pattern: cryptography.hazmat.primitives.ciphers.algorithms.TripleDES(...)
          - pattern: Crypto.Cipher.DES3.new(...)
          - pattern: Cryptodome.Cipher.DES3.new(...)
    message: >-
      3DES has 112-bit effective key strength -- broken classically and quantum-vulnerable. NIST deprecated
      3DES in 2023. Migrate to AES-256-GCM.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
        - post-quantum
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: HIGH
      quantum_vulnerable: true
      quantum_attack: "Grover's Algorithm"
      quantum_risk_score: 8
      post_quantum_alternatives:
        - "AES-256"
      references:
        - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf

  - id: python-use-of-blowfish
    patterns:
      - pattern-either:
          - pattern: cryptography.hazmat.primitives.ciphers.algorithms.Blowfish(...)
          - pattern: Crypto.Cipher.Blowfish.new(...)
          - pattern: Cryptodome.Cipher.Blowfish.new(...)
    message: >-
      Blowfish uses 64-bit blocks, making it vulnerable to birthday attacks, and provides no post-quantum
      security. Migrate to AES-256-GCM.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
        - post-quantum
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: HIGH
      quantum_vulnerable: true
      quantum_attack: "Grover's Algorithm"
      quantum_risk_score: 7
      post_quantum_alternatives:
        - "AES-256-GCM"

  - id: python-use-of-rc4
    patterns:
      - pattern-either:
          - pattern: cryptography.hazmat.primitives.ciphers.algorithms.ARC4(...)
          - pattern: Crypto.Cipher.ARC4.new(...)
          - pattern: Cryptodome.Cipher.ARC4.new(...)
    message: >-
      RC4 is completely broken and banned by RFC 7465. Migrate to AES-256-GCM or ChaCha20-Poly1305.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: HIGH
      quantum_vulnerable: true
      quantum_risk_score: 9
      post_quantum_alternatives:
        - "AES-256-GCM"
        - "ChaCha20-Poly1305"

  - id: python-aes-ecb-mode
    patterns:
      - pattern-either:
          - pattern: cryptography.hazmat.primitives.ciphers.modes.ECB(...)
          - pattern: Crypto.Cipher.AES.new($KEY, Crypto.Cipher.AES.MODE_ECB)
          - pattern: Cryptodome.Cipher.AES.new($KEY, Cryptodome.Cipher.AES.MODE_ECB)
    message: >-
      AES in ECB mode leaks data patterns -- identical plaintext blocks produce identical ciphertext. Use
      AES-256-GCM for authenticated encryption.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: MEDIUM
      impact: HIGH
      quantum_vulnerable: false
      quantum_risk_score: 6
      references:
        - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/

  - id: python-cryptography-insecure-hash
    patterns:
      - pattern-either:
          - pattern: hashes.MD5()
          - pattern: hashes.SHA1()
    message: >-
      MD5 is cryptographically broken and quantum-weakened by Grover's algorithm -- effective security
      drops from 128 to 64 bits. Use SHA-256, SHA-384, or SHA-3.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - post-quantum
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
        - "CWE-328: Use of Weak Hash"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: HIGH
      quantum_vulnerable: true
      quantum_attack: "Grover's Algorithm"
      quantum_risk_score: 9

  - id: python-cbc-mode-no-authentication
    patterns:
      - pattern-either:
          - pattern: cryptography.hazmat.primitives.ciphers.modes.CBC(...)
          - pattern: Crypto.Cipher.AES.new($KEY, Crypto.Cipher.AES.MODE_CBC, ...)
          - pattern: Cryptodome.Cipher.AES.new($KEY, Cryptodome.Cipher.AES.MODE_CBC, ...)
    message: >-
      AES-CBC without authentication is vulnerable to padding oracle and bit-flipping attacks. Use
      AES-256-GCM for authenticated encryption.
    severity: WARNING
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
        - "CWE-649: Reliance on Obfuscation or Encryption without Integrity Checking"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: MEDIUM
      impact: HIGH
      quantum_vulnerable: false
      quantum_risk_score: 6

  - id: python-weak-random
    patterns:
      - pattern-either:
          - pattern: random.random(...)
          - pattern: random.randint(...)
          - pattern: random.choice(...)
          - pattern: random.randrange(...)
    message: >-
      Non-cryptographic PRNG used for security-sensitive operations -- output is predictable. Use a
      cryptographically secure random number generator.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - crypto
      cwe:
        - "CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: MEDIUM
      likelihood: MEDIUM
      impact: HIGH
      quantum_vulnerable: false
      quantum_risk_score: 7
      references:
        - https://docs.python.org/3/library/secrets.html

  - id: python-hardcoded-crypto-key
    patterns:
      - pattern-either:
          - pattern: |
              $KEY = b"..."
              ...
              $CIPHER = $ALGO.new($KEY, ...)
          - pattern: |
              $KEY = "..."
              ...
              $CIPHER = $ALGO.new($KEY, ...)
          - pattern: |
              $CIPHER = $ALGO.new(b"...", ...)
          - pattern: |
              $CIPHER = $ALGO.new("...", ...)
    message: >-
      Hardcoded cryptographic key in source code exposes key material to anyone with code access. Use
      environment variables or a dedicated secrets manager.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - crypto
      cwe:
        - "CWE-798: Use of Hard-coded Credentials"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: MEDIUM
      likelihood: HIGH
      impact: CRITICAL
      quantum_vulnerable: false
      quantum_risk_score: 8
      references:
        - https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password

  - id: python-static-iv
    patterns:
      - pattern-either:
          - pattern: |
              $IV = b"..."
              ...
              $MODE = modes.$CIPHER_MODE($IV)
          - pattern: |
              $IV = b"\x00" * $N
              ...
              $MODE = modes.$CIPHER_MODE($IV)
          - pattern: |
              modes.$CIPHER_MODE(b"...")
    message: >-
      Static or hardcoded IV breaks IND-CPA security -- identical plaintexts produce identical ciphertext.
      Generate a fresh random IV for every encryption operation.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
      cwe:
        - "CWE-329: Not Using a Random IV with CBC Mode"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: MEDIUM
      likelihood: MEDIUM
      impact: HIGH
      quantum_vulnerable: false
      quantum_risk_score: 7
      references:
        - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/

  - id: python-weak-pbkdf2-iterations
    patterns:
      - pattern-either:
          - pattern: hashlib.pbkdf2_hmac($HASH, $PASSWORD, $SALT, $ITERATIONS, ...)
          - pattern: Crypto.Protocol.KDF.PBKDF2($PASSWORD, $SALT, ..., count=$ITERATIONS, ...)
          - pattern: Cryptodome.Protocol.KDF.PBKDF2($PASSWORD, $SALT, ..., count=$ITERATIONS, ...)
      - metavariable-comparison:
          metavariable: $ITERATIONS
          comparison: $ITERATIONS < 100000
    message: >-
      Insufficient PBKDF2 iterations make the derived key brute-forceable. Use at least 310,000 iterations
      (NIST SP 800-132) or switch to Argon2.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
      cwe:
        - "CWE-916: Use of Password Hash With Insufficient Computational Effort"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: HIGH
      quantum_vulnerable: true
      quantum_attack: "Grover's Algorithm (accelerates brute-force)"
      quantum_risk_score: 8
      post_quantum_alternatives:
        - "Argon2id"
        - "scrypt"
      references:
        - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
        - https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf

  - id: python-weak-rsa-key-size
    patterns:
      - pattern-either:
          - pattern: RSA.generate(512, ...)
          - pattern: RSA.generate(1024, ...)
          - pattern: RSA.generate(2048, ...)
          - pattern: rsa.generate_private_key($EXPONENT, 512, ...)
          - pattern: rsa.generate_private_key($EXPONENT, 1024, ...)
          - pattern: rsa.generate_private_key($EXPONENT, 2048, ...)
          - pattern: rsa.generate_private_key(..., key_size=512, ...)
          - pattern: rsa.generate_private_key(..., key_size=1024, ...)
          - pattern: rsa.generate_private_key(..., key_size=2048, ...)
    message: >-
      RSA key size $SIZE bits is too small and quantum-vulnerable. RSA is broken by Shor's algorithm
      regardless of key size. Migrate to ML-KEM (FIPS 203) for key encapsulation or ML-DSA (FIPS 204) for
      signatures.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycrypto
        - post-quantum
      cwe:
        - "CWE-326: Inadequate Encryption Strength"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: CRITICAL
      quantum_vulnerable: true
      quantum_attack: "Shor's Algorithm"
      quantum_risk_score: 10
      post_quantum_alternatives:
        - "CRYSTALS-Kyber (encryption/KEM)"
        - "CRYSTALS-Dilithium (signatures)"
        - "FALCON (signatures)"
      references:
        - https://csrc.nist.gov/projects/post-quantum-cryptography
        - https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf

  - id: python-md2-hash
    patterns:
      - pattern-either:
          - pattern: hashlib.new("md2", ...)
          - pattern: hashlib.new('md2', ...)
          - pattern: Crypto.Hash.MD2.new(...)
          - pattern: Cryptodome.Hash.MD2.new(...)
    message: >-
      QUANTUM VULNERABILITY: MD2 hash function is cryptographically broken and has been deprecated since
      2011 (RFC 6149). It is vulnerable to collision attacks and preimage attacks. Grover's algorithm on
      quantum computers further reduces its already weak security.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycryptodome
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: HIGH
      quantum_vulnerable: true
      quantum_attack: "Grover's Algorithm"
      quantum_risk_score: 10
      post_quantum_alternatives:
        - "SHA-256"
        - "SHA-3"
        - "SPHINCS+"
      references:
        - https://tools.ietf.org/html/rfc6149

  - id: python-weak-dsa-key
    patterns:
      - pattern-either:
          - pattern: DSA.generate($BITS, ...)
          - pattern: dsa.generate_private_key($SIZE, ...)
    message: >-
      DH/DSA is broken by Shor's algorithm. Migrate to ML-KEM (FIPS 203) for key exchange or ML-DSA (FIPS
      204) for signatures.
    severity: ERROR
    languages: [python]
    metadata:
      category: security
      technology:
        - python
        - cryptography
        - pycrypto
        - post-quantum
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 - Cryptographic Failures
      confidence: HIGH
      likelihood: HIGH
      impact: CRITICAL
      quantum_vulnerable: true
      quantum_attack: "Shor's Algorithm"
      quantum_risk_score: 10
      post_quantum_alternatives:
        - "CRYSTALS-Dilithium"
        - "FALCON"
        - "SPHINCS+"
      references:
        - https://csrc.nist.gov/projects/post-quantum-cryptography
        - https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
