fix(security): consolidation & securite phase 1 (#84, BUG-021 a BUG-034)
- sanitizer XSS serveur (markdown + page de partage) [BUG-021/022] - rate-limit/lockout MFA [BUG-023] - isolation vaults par segments [BUG-024] - caps regex ReDoS [BUG-025] - SSRF webhooks + secrets externalises [BUG-026] - rotation/revocation des jetons [BUG-027] - politique de mot de passe + invalidation sessions [BUG-028] - verrous users.json [BUG-029] - IP reelle dans les audits [BUG-030] - rate-limit par compte [BUG-031] - symlinks hors vault ignores [BUG-032] - recherche simple via inverted index [BUG-033] - token en memoire + cookie HttpOnly, CSP durcie [BUG-034] Tests: pytest 961 passed / 6 skipped, ruff 0, mypy 0, frontend vert.
This commit is contained in:
@@ -13,6 +13,32 @@ ph = PasswordHasher(
|
||||
salt_len=16,
|
||||
)
|
||||
|
||||
# Password policy (BUG-028). Applied by the API validators at account creation
|
||||
# and password change so the rules stay consistent across both paths.
|
||||
MIN_PASSWORD_LENGTH = 8
|
||||
MAX_PASSWORD_LENGTH = 128
|
||||
|
||||
|
||||
def validate_password_strength(password: str) -> str:
|
||||
"""Validate a plaintext password against the project policy.
|
||||
|
||||
Args:
|
||||
password: Candidate password.
|
||||
|
||||
Returns:
|
||||
The password unchanged when valid.
|
||||
|
||||
Raises:
|
||||
ValueError: When the password is too short, too long or blank.
|
||||
"""
|
||||
if password is None or len(password) < MIN_PASSWORD_LENGTH:
|
||||
raise ValueError(f"Minimum {MIN_PASSWORD_LENGTH} caractères")
|
||||
if len(password) > MAX_PASSWORD_LENGTH:
|
||||
raise ValueError(f"Maximum {MAX_PASSWORD_LENGTH} caractères")
|
||||
if not password.strip():
|
||||
raise ValueError("Le mot de passe ne peut pas être vide")
|
||||
return password
|
||||
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
"""Hash a password with Argon2id."""
|
||||
|
||||
Reference in New Issue
Block a user