python.django.security.passwords.password-empty-string.password-empty-string

profile photo of semgrepsemgrep
Author
8,139
Download Count*

'$VAR' is the empty string and is being used to set the password on '$MODEL'. If you meant to set an unusable password, set the password to None or call 'set_unusable_password()'.

Run Locally

Run in CI

Defintion

rules:
  - id: password-empty-string
    message: "'$VAR' is the empty string and is being used to set the password on
      '$MODEL'. If you meant to set an unusable password, set the password to
      None or call 'set_unusable_password()'."
    metadata:
      cwe:
        - "CWE-521: Weak Password Requirements"
      owasp:
        - A07:2021 - Identification and Authentication Failures
      references:
        - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password
      category: security
      technology:
        - django
      subcategory:
        - vuln
      likelihood: LOW
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Authentication
    patterns:
      - pattern-either:
          - pattern: |
              $MODEL.set_password($EMPTY)
              ...
              $MODEL.save()
          - pattern: |
              $VAR = $EMPTY
              ...
              $MODEL.set_password($VAR)
              ...
              $MODEL.save()
      - metavariable-regex:
          metavariable: $EMPTY
          regex: (\'\'|\"\")
    languages:
      - python
    severity: ERROR

Examples

password-empty-string.py

import os
import ujson
from typing import Any, Dict, List

from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.test import Client

from tests import example_user
from models import UserProfile
from backend import EmailAuthBackend

def test_email_auth_backend_empty_password(user_profile: UserProfile) -> None:
    user_profile = example_user('hamlet')
    # ok: password-empty-string
    password = "testpassword"
    user_profile.set_password(password)
    user_profile.save()

    # First, verify authentication works with the a nonempty
    # password so we know we've set up the test correctly.
    self.assertIsNotNone(EmailAuthBackend().authenticate(username=self.example_email('hamlet'), password=password))

    # Now do the same test with the empty string as the password.
    # ruleid: password-empty-string
    password = ""
    user_profile.set_password(password)
    user_profile.save()
    self.assertIsNone(EmailAuthBackend().authenticate(username=self.example_email('hamlet'), password=password))

    # Now do the same test with the empty string as the password.
    # ruleid: password-empty-string
    password = ''
    user_profile.set_password(password)
    user_profile.save()
    self.assertIsNone(EmailAuthBackend().authenticate(username=self.example_email('hamlet'), password=password))