Add backdoor to login as other users (in debug mode only)

This commit is contained in:
Yohann D'ANELLO 2020-07-30 12:50:48 +02:00
parent b49db39080
commit fb775de923
6 changed files with 53 additions and 7 deletions

View File

@ -3,9 +3,12 @@
import hashlib
from django.contrib.auth.hashers import PBKDF2PasswordHasher
from django.conf import settings
from django.contrib.auth.hashers import PBKDF2PasswordHasher, BasePasswordHasher
from django.utils.crypto import constant_time_compare
from note_kfet.middlewares import get_current_authenticated_user, get_current_session
class CustomNK15Hasher(PBKDF2PasswordHasher):
"""
@ -20,8 +23,37 @@ class CustomNK15Hasher(PBKDF2PasswordHasher):
"""
algorithm = "custom_nk15"
def must_update(self, encoded):
if settings.DEBUG:
current_user = get_current_authenticated_user()
if current_user is not None and current_user.is_superuser:
return False
return True
def verify(self, password, encoded):
if settings.DEBUG:
current_user = get_current_authenticated_user()
if current_user is not None and current_user.is_superuser\
and get_current_session().get("permission_mask", -1) >= 42:
return True
if '|' in encoded:
salt, db_hashed_pass = encoded.split('$')[2].split('|')
return constant_time_compare(hashlib.sha256((salt + password).encode("utf-8")).hexdigest(), db_hashed_pass)
return super().verify(password, encoded)
class DebugSuperuserBackdoor(PBKDF2PasswordHasher):
"""
In debug mode and during the beta, superusers can login into other accounts for tests.
"""
def must_update(self, encoded):
return False
def verify(self, password, encoded):
if settings.DEBUG:
current_user = get_current_authenticated_user()
if current_user is not None and current_user.is_superuser\
and get_current_session().get("permission_mask", -1) >= 42:
return True
return super().verify(password, encoded)

View File

@ -6,6 +6,7 @@ from datetime import datetime, timedelta
from PIL import Image
from django.conf import settings
from django.contrib.auth import logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.auth.views import LoginView
@ -21,6 +22,7 @@ from note.forms import ImageForm
from note.models import Alias, NoteUser
from note.models.transactions import Transaction, SpecialTransaction
from note.tables import HistoryTable, AliasTable
from note_kfet.middlewares import _set_current_user_and_ip
from permission.backends import PermissionBackend
from permission.models import Role
from permission.views import ProtectQuerysetMixin
@ -38,6 +40,8 @@ class CustomLoginView(LoginView):
form_class = CustomAuthenticationForm
def form_valid(self, form):
logout(self.request)
_set_current_user_and_ip(form.get_user(), self.request.session, None)
self.request.session['permission_mask'] = form.cleaned_data['permission_mask'].rank
return super().form_valid(form)

View File

@ -1,7 +1,6 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User, AnonymousUser
from django.contrib.contenttypes.models import ContentType
@ -137,7 +136,7 @@ class PermissionBackend(ModelBackend):
if sess is not None and sess.session_key is None:
return False
if user_obj.is_superuser and get_current_session().get("permission_mask", -1) >= 42:
if user_obj.is_superuser and sess.get("permission_mask", -1) >= 42:
return True
if obj is None:

View File

@ -4,6 +4,7 @@
from functools import lru_cache
from time import time
from django.conf import settings
from django.contrib.sessions.models import Session
from note_kfet.middlewares import get_current_session
@ -32,6 +33,10 @@ def memoize(f):
sess_funs = new_sess_funs
def func(*args, **kwargs):
if settings.DEBUG:
# Don't memoize in DEBUG mode
return f(*args, **kwargs)
nonlocal last_collect
if time() - last_collect > 60:

View File

@ -1,6 +1,6 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.utils.translation import gettext_lazy as _
from note_kfet.middlewares import get_current_authenticated_user
@ -50,6 +50,10 @@ def pre_save_object(sender, instance, **kwargs):
# In the other case, we check if he/she has the right to change one field
previous = qs.get()
if isinstance(instance, User) and instance.last_login != previous.last_login:
pass #return
for field in instance._meta.fields:
field_name = field.name
old_value = getattr(previous, field.name)

View File

@ -57,6 +57,8 @@ if "cas_server" in INSTALLED_APPS:
if "logs" in INSTALLED_APPS:
MIDDLEWARE += ('note_kfet.middlewares.SessionMiddleware',)
if "debug_toolbar" in INSTALLED_APPS:
if DEBUG:
PASSWORD_HASHERS += ['member.hashers.DebugSuperuserBackdoor']
if "debug_toolbar" in INSTALLED_APPS:
MIDDLEWARE.insert(1, "debug_toolbar.middleware.DebugToolbarMiddleware")
INTERNAL_IPS = ['127.0.0.1']