version0.4.1 Общие исправления
This commit is contained in:
@@ -23,7 +23,11 @@ SSL_KEY = os.environ.get("SSL_KEY", "")
|
|||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = os.environ.get("FLASK_SECRET", secrets.token_hex(32))
|
app.secret_key = os.environ.get("FLASK_SECRET", secrets.token_hex(32))
|
||||||
app.config["SESSION_COOKIE_SAMESITE"] = "Lax"
|
app.config["SESSION_COOKIE_SAMESITE"] = "Lax"
|
||||||
app.config["SESSION_COOKIE_SECURE"] = bool(SSL_CERT)
|
# SESSION_COOKIE_SECURE не задаём статически — это ломает логин, если
|
||||||
|
# SSL_CERT прописан в env, но gunicorn по факту поднялся на HTTP
|
||||||
|
# (например, сертификат ещё не физически на диске, или используется
|
||||||
|
# SSH-туннель без TLS). Вместо этого выставляем Secure динамически
|
||||||
|
# по факту запроса — см. _set_cookie_secure_dynamically ниже.
|
||||||
app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(hours=8)
|
app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(hours=8)
|
||||||
|
|
||||||
# ── Rate limiter ─────────────────────────────────────────────────────────────
|
# ── Rate limiter ─────────────────────────────────────────────────────────────
|
||||||
@@ -595,6 +599,27 @@ def check_secret_path():
|
|||||||
if not (path == allowed_prefix or path.startswith(allowed_prefix + "/")):
|
if not (path == allowed_prefix or path.startswith(allowed_prefix + "/")):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
# ── Динамическая правка Secure-флага на cookie сессии ────────────────────────
|
||||||
|
# Если выставить Secure статически по наличию SSL_CERT в env, можно словить
|
||||||
|
# ситуацию когда сертификат прописан, но запрос реально пришёл по HTTP
|
||||||
|
# (gunicorn не поднял TLS, SSH-туннель без TLS и т.п.) — тогда браузер
|
||||||
|
# тихо отбросит cookie с флагом Secure, и человек не сможет войти, видя
|
||||||
|
# при этом "успешный" логин без какой-либо ошибки. Поэтому проверяем
|
||||||
|
# request.is_secure на каждый ответ и правим флаг по факту.
|
||||||
|
@app.after_request
|
||||||
|
def fix_session_cookie_secure(response):
|
||||||
|
if not request.is_secure:
|
||||||
|
return response
|
||||||
|
set_cookie_headers = response.headers.getlist("Set-Cookie")
|
||||||
|
if not set_cookie_headers:
|
||||||
|
return response
|
||||||
|
response.headers.remove("Set-Cookie")
|
||||||
|
for header in set_cookie_headers:
|
||||||
|
if app.session_cookie_name in header and "Secure" not in header:
|
||||||
|
header += "; Secure"
|
||||||
|
response.headers.add("Set-Cookie", header)
|
||||||
|
return response
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
port = int(os.environ.get("PANEL_PORT", "8080"))
|
port = int(os.environ.get("PANEL_PORT", "8080"))
|
||||||
ssl_ctx = None
|
ssl_ctx = None
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ function showPage(id,btn){
|
|||||||
if(id==='dashboard')loadDashboard();
|
if(id==='dashboard')loadDashboard();
|
||||||
if(id==='users')loadUsers();
|
if(id==='users')loadUsers();
|
||||||
if(id==='ssl')loadSSL();
|
if(id==='ssl')loadSSL();
|
||||||
|
if(id==='security')loadSecurityPage();
|
||||||
}
|
}
|
||||||
function openModal(title,html){
|
function openModal(title,html){
|
||||||
document.getElementById('modal-title-text').textContent=title;
|
document.getElementById('modal-title-text').textContent=title;
|
||||||
|
|||||||
Reference in New Issue
Block a user