python.django.security.passwords.use-none-for-password-default.use-none-for-password-default
Verifed by r2c
Community Favorite

Author
100,049
Download Count*
License
'$VAR' is using the empty string as its default and is being used to set the password on '$MODEL'. If you meant to set an unusable password, set the default value to 'None' or call 'set_unusable_password()'.
Run Locally
Run in CI
Defintion
rules:
- id: use-none-for-password-default
message: "'$VAR' is using the empty string as its default and is being used to
set the password on '$MODEL'. If you meant to set an unusable password,
set the default value 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: MEDIUM
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- python
severity: ERROR
patterns:
- pattern-either:
- pattern: |
$VAR = request.$W.get($X, $EMPTY)
...
$MODEL.set_password($VAR)
...
$MODEL.save(...)
- pattern: |
def $F(..., $VAR=$EMPTY, ...):
...
$MODEL.set_password($VAR)
- focus-metavariable: $EMPTY
fix: |
None
Examples
use-none-for-password-default.py
from django.contrib import auth
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import PermissionDenied, ValidationError
from django.utils.translation import gettext as _
from django.views.decorators.csrf import csrf_protect
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from ...conf import settings
from ...core.decorators import require_dict_data
from ...core.mail import mail_user
from ..bans import get_user_ban
from ..forms.auth import AuthenticationForm, ResendActivationForm, ResetPasswordForm
from ..serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
from ..tokens import (
is_password_change_token_valid,
make_activation_token,
make_password_change_token,
)
from .rest_permissions import UnbannedAnonOnly, UnbannedOnly
User = auth.get_user_model()
BaseUserManager = User.__class__
class PasswordChangeFailed(Exception):
pass
def change_forgotten_password(request, pk, token):
"""
POST /auth/change-password/user/token/ with CSRF and new password
will change forgotten password
"""
if request.settings.enable_sso:
raise PermissionDenied(_("Please use the 3rd party site to authenticate."))
invalid_message = _("Form link is invalid. Please try again.")
expired_message = _("Your link has expired. Please request new one.")
try:
try:
user = User.objects.get(pk=pk, is_active=True)
except User.DoesNotExist:
raise PasswordChangeFailed(invalid_message)
if request.user.is_authenticated and request.user.id != user.id:
raise PasswordChangeFailed(invalid_message)
if not is_password_change_token_valid(user, token):
raise PasswordChangeFailed(invalid_message)
if user.requires_activation:
raise PasswordChangeFailed(expired_message)
if get_user_ban(user, request.cache_versions):
raise PasswordChangeFailed(expired_message)
except PasswordChangeFailed as e:
return Response({"detail": e.args[0]}, status=status.HTTP_400_BAD_REQUEST)
try:
# ruleid: use-none-for-password-default
new_password = request.data.get("password", "")
validate_password(new_password, user=user)
user.set_password(new_password)
user.save()
except ValidationError as e:
return Response({"detail": e.messages[0]}, status=status.HTTP_400_BAD_REQUEST)
return Response({"username": user.username})
class UserManager(BaseUserManager):
# ruleid: use-none-for-password-default
def create_user(self, email, password=""):
"""
Creates and saves a Poster with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(email=self.normalize_email(email))
user.set_password(password)
user.save(using=self._db)
return user
Short Link: https://sg.run/zvBW