1
0
forked from ScoDoc/ScoDoc

Renforce vérification formulaire de login pour éviter de déclencher une erreur SQL

This commit is contained in:
Emmanuel Viennet 2023-03-17 19:33:10 +01:00
parent 60567671a0
commit e482e6bd3d
2 changed files with 18 additions and 6 deletions

View File

@ -32,7 +32,7 @@ from app.scodoc import sco_etud # a deplacer dans scu
VALID_LOGIN_EXP = re.compile(r"^[a-zA-Z0-9@\\\-_\.]+$") VALID_LOGIN_EXP = re.compile(r"^[a-zA-Z0-9@\\\-_\.]+$")
def is_valid_password(cleartxt): def is_valid_password(cleartxt) -> bool:
"""Check password. """Check password.
returns True if OK. returns True if OK.
""" """
@ -49,6 +49,15 @@ def is_valid_password(cleartxt):
return False return False
def invalid_user_name(user_name: str) -> bool:
"Check that user_name (aka login) is invalid"
return (
(len(user_name) < 2)
or (len(user_name) >= USERNAME_STR_LEN)
or not VALID_LOGIN_EXP.match(user_name)
)
class User(UserMixin, db.Model): class User(UserMixin, db.Model):
"""ScoDoc users, handled by Flask / SQLAlchemy""" """ScoDoc users, handled by Flask / SQLAlchemy"""
@ -108,7 +117,7 @@ class User(UserMixin, db.Model):
self.roles = [] self.roles = []
self.user_roles = [] self.user_roles = []
# check login: # check login:
if kwargs.get("user_name") and not VALID_LOGIN_EXP.match(kwargs["user_name"]): if kwargs.get("user_name") and invalid_user_name(kwargs["user_name"]):
raise ValueError(f"invalid user_name: {kwargs['user_name']}") raise ValueError(f"invalid user_name: {kwargs['user_name']}")
super(User, self).__init__(**kwargs) super(User, self).__init__(**kwargs)
# Ajoute roles: # Ajoute roles:
@ -287,7 +296,7 @@ class User(UserMixin, db.Model):
self.user_name = data["user_name"] self.user_name = data["user_name"]
if "password" in data: if "password" in data:
self.set_password(data["password"]) self.set_password(data["password"])
if not VALID_LOGIN_EXP.match(self.user_name): if not invalid_user_name(self.user_name):
raise ValueError(f"invalid user_name: {self.user_name}") raise ValueError(f"invalid user_name: {self.user_name}")
# Roles: roles_string is "Ens_RT, Secr_RT, ..." # Roles: roles_string is "Ens_RT, Secr_RT, ..."
if "roles_string" in data: if "roles_string" in data:

View File

@ -19,8 +19,7 @@ from app.auth.forms import (
ResetPasswordRequestForm, ResetPasswordRequestForm,
UserCreationForm, UserCreationForm,
) )
from app.auth.models import Role from app.auth.models import Role, User, invalid_user_name
from app.auth.models import User
from app.auth.email import send_password_reset_email from app.auth.email import send_password_reset_email
from app.decorators import admin_required from app.decorators import admin_required
from app.models.config import ScoDocSiteConfig from app.models.config import ScoDocSiteConfig
@ -34,7 +33,11 @@ def _login_form():
"""le formulaire de login, avec un lien CAS s'il est configuré.""" """le formulaire de login, avec un lien CAS s'il est configuré."""
form = LoginForm() form = LoginForm()
if form.validate_on_submit(): if form.validate_on_submit():
user = User.query.filter_by(user_name=form.user_name.data).first() # note: ceci est la première requête SQL déclenchée par un utilisateur arrivant
if invalid_user_name(form.user_name.data):
user = None
else:
user = User.query.filter_by(user_name=form.user_name.data).first()
if user is None or not user.check_password(form.password.data): if user is None or not user.check_password(form.password.data):
current_app.logger.info("login: invalid (%s)", form.user_name.data) current_app.logger.info("login: invalid (%s)", form.user_name.data)
flash(_("Nom ou mot de passe invalide")) flash(_("Nom ou mot de passe invalide"))