1
0
Fork 0

improve security and fix error msg

- Instead of passing the user as a hidden form element, we use a session variable.
- Introduces a 60 second limit on completing the login, and an exponentially increasing delay to attempt to login with 2FA if the code is entered incorrectly.
- use proper Django form error when incorrect otp value entered
This commit is contained in:
Hugh Rundle 2022-09-18 16:32:42 +10:00
parent 9d12b7caff
commit 6db4fb39ed
5 changed files with 58 additions and 55 deletions

View file

@ -4,8 +4,6 @@ from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
import pyotp
from bookwyrm import models
from bookwyrm.models.fields import ClearableFileInputWithWarning
from .custom_form import CustomForm
@ -118,32 +116,3 @@ class ConfirmPasswordForm(CustomForm):
if not self.instance.check_password(password):
self.add_error("password", _("Incorrect Password"))
class Confirm2FAForm(CustomForm):
otp = forms.CharField(max_length=6, min_length=6, widget=forms.TextInput)
# IDK if we need this?
class Meta:
model = models.User
fields = ["otp_secret"]
def clean(self):
"""Check otp matches"""
otp = self.data.get("otp")
totp = pyotp.TOTP(self.instance.otp_secret)
if not totp.verify(otp):
# maybe it's a backup code?
hotp = pyotp.HOTP(self.instance.otp_secret)
hotp_count = (
self.instance.hotp_count if self.instance.hotp_count is not None else 0
)
if not hotp.verify(otp, hotp_count):
self.add_error("otp", _("Code does not match"))
# TODO: backup codes
# increment the user hotp_count if it was an HOTP
# self.instance.hotp_count = hotp_count + 1
# self.instance.save(broadcast=False, update_fields=["hotp_count"])