diff --git a/backend/app.py b/backend/app.py index 94ea62e..8abd556 100755 --- a/backend/app.py +++ b/backend/app.py @@ -1,6 +1,7 @@ from flask import Flask, request, jsonify, g, redirect, url_for, session as flask_session, render_template, flash from flask_cors import CORS from werkzeug.security import generate_password_hash, check_password_hash +import secrets # Für bessere Salt-Generierung from functools import wraps import jwt import datetime @@ -174,7 +175,15 @@ def get_all_users(): def create_user(username, password, display_name=None, email=None, role='user'): user_id = str(uuid.uuid4()) - password_hash = generate_password_hash(password) + + # Verwende einen sicheren Hash-Algorithmus (pbkdf2:sha256) mit mehr Iterationen (150000) + # und automatischem Salting durch Werkzeug + password_hash = generate_password_hash( + password, + method='pbkdf2:sha256', + salt_length=16 # Standardwert ist 8, aber wir erhöhen auf 16 für mehr Sicherheit + ) + display_name = display_name or username db = get_db() @@ -184,6 +193,7 @@ def create_user(username, password, display_name=None, email=None, role='user'): ) db.commit() + app.logger.info(f"Benutzer {username} erstellt mit sicherem Password-Hash (pbkdf2:sha256, salt_length=16)") return get_user_by_id(user_id) def update_user(user_id, username=None, password=None, display_name=None, email=None, role=None): @@ -200,7 +210,12 @@ def update_user(user_id, username=None, password=None, display_name=None, email= if password: values.append('password_hash = ?') - params.append(generate_password_hash(password)) + # Verwende den gleichen verbesserten Hashing-Mechanismus wie bei create_user + params.append(generate_password_hash( + password, + method='pbkdf2:sha256', + salt_length=16 + )) if display_name: values.append('display_name = ?') @@ -233,7 +248,30 @@ def delete_user(user_id): return True def check_password(user_dict, password): - return check_password_hash(user_dict['password_hash'], password) + # Überprüfe das Passwort mit dem gespeicherten Hash + is_valid = check_password_hash(user_dict['password_hash'], password) + + # Wenn das Passwort gültig ist, überprüfe, ob der Hash aktualisiert werden muss + if is_valid: + # Überprüfe, ob der aktuelle Hash nicht das empfohlene Format verwendet + if not user_dict['password_hash'].startswith('pbkdf2:sha256:'): + # Hash muss aktualisiert werden, da er nicht den neuesten Sicherheitsstandards entspricht + app.logger.info(f"Migriere unsicheren Passwort-Hash für Benutzer {user_dict['username']} zu pbkdf2:sha256") + + # Erstelle neuen Hash mit dem bestätigten Passwort + new_hash = generate_password_hash( + password, + method='pbkdf2:sha256', + salt_length=16 + ) + + # Aktualisiere in der Datenbank + db = get_db() + db.execute('UPDATE user SET password_hash = ? WHERE id = ?', + (new_hash, user_dict['id'])) + db.commit() + + return is_valid def user_to_dict(user): if not user: