ruby.lang.security.md5-used-as-password.md5-used-as-password

profile photo of semgrepsemgrep
Author
unknown
Download Count*

It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Instead, use a suitable password hashing function such as bcrypt. You can use the bcrypt gem.

Run Locally

Run in CI

Defintion

rules:
  - id: md5-used-as-password
    languages:
      - ruby
    severity: WARNING
    message: It looks like MD5 is used as a password hash. MD5 is not considered a
      secure password hash because it can be cracked by an attacker in a short
      amount of time. Instead, use a suitable password hashing function such as
      bcrypt. You can use the `bcrypt` gem.
    metadata:
      category: security
      technology:
        - md5
      references:
        - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html
        - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords
        - https://github.com/returntocorp/semgrep-rules/issues/1609
      owasp:
        - A03:2017 - Sensitive Data Exposure
        - A02:2021 - Cryptographic Failures
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      subcategory:
        - vuln
      likelihood: HIGH
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cryptographic Issues
    mode: taint
    pattern-sources:
      - pattern: Digest::MD5
    pattern-sinks:
      - patterns:
          - pattern: $FUNCTION(...);
          - metavariable-regex:
              metavariable: $FUNCTION
              regex: (?i)(.*password.*)

Examples

md5-used-as-password.rb

require 'digest'

#### True Positives ####
def ex1 (user, pwtext)
    # ruleid: md5-used-as-password
    user.set_password Digest::MD5.hexdigest pwtext
end

def ex2 (user, pwtext)
    md5 = Digest::MD5.new
    md5.update pwtext
    md5 << salt(pwtext)
    dig = md5.hexdigest
    # ruleid: md5-used-as-password
    user.set_password dig
end

#### True Negatives ####
def ok1 (user, pwtext)
    # ok: md5-used-as-password
    user.set_password Digest::SHA256.hexdigest pwtext
end

def ok2 (user, pwtext)
    sha = Digest::SHA256.new
    sha.update pwtext
    sha << salt(pwtext)
    dig = sha.hexdigest
    # ok: md5-used-as-password
    user.set_password dig
end