security: 环境变量密钥、密码加盐哈希、CSRF 防护

- config.py/web_server.py 支持环境变量注入 STF_TOKEN/WEB_SECRET_KEY,新增 .env 加载和 .env.example;.env 加入 gitignore
- 用户密码从裸 SHA-256 改为 werkzeug 加盐哈希(scrypt),旧哈希登录时自动升级
- CSRF:session token + X-CSRF-Token 请求头校验非 GET 请求,前端自动携带
This commit is contained in:
2026-08-08 21:29:39 +08:00
parent afeb0902a1
commit 838886e043
6 changed files with 111 additions and 10 deletions
+16 -3
View File
@@ -22,6 +22,7 @@ from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from sqlalchemy import event, text
from sqlalchemy.engine import Engine
from werkzeug.security import generate_password_hash, check_password_hash
from core.logger import get_logger
@@ -47,14 +48,26 @@ class User(UserMixin, db.Model):
"""后台用户。"""
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(120), nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
is_admin = db.Column(db.Boolean, default=True)
def set_password(self, password):
self.password_hash = hashlib.sha256(password.encode()).hexdigest()
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return self.password_hash == hashlib.sha256(password.encode()).hexdigest()
"""校验密码。兼容旧 SHA-256 哈希(匹配则自动升级为新哈希)。"""
ph = self.password_hash or ""
if ph and not ph.startswith(("pbkdf2:", "scrypt:")):
# 旧版裸 SHA-256:比对通过则升级为加盐哈希
if hashlib.sha256(password.encode()).hexdigest() == ph:
self.set_password(password)
try:
db.session.commit()
except Exception:
pass
return True
return False
return check_password_hash(ph, password)
def __repr__(self):
return f"<User {self.username}>"