ajouter des sécurité sur les URL, les Roles, les mdp
This commit is contained in:
@@ -5,10 +5,13 @@ the Flask application instance.
|
||||
"""
|
||||
|
||||
import os
|
||||
from flask import Flask
|
||||
from extensions import db, login_manager, csrf, hash_password, check_password
|
||||
from flask import Flask, request, redirect
|
||||
from extensions import db, login_manager, csrf, hash_password, check_password, limiter
|
||||
from sqlalchemy import text
|
||||
import markupsafe
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def nl2br(value):
|
||||
@@ -30,10 +33,11 @@ def create_app():
|
||||
|
||||
Initializes Flask with:
|
||||
- Secret key for session security
|
||||
- SQLite database configuration
|
||||
- Database configuration
|
||||
- CSRF protection
|
||||
- Login manager
|
||||
- All route blueprints
|
||||
- Security headers and HTTPS redirects
|
||||
|
||||
Handles database initialization and seeding with sample data if empty.
|
||||
|
||||
@@ -41,14 +45,23 @@ def create_app():
|
||||
Flask: Configured Flask application instance.
|
||||
"""
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'team-tryouts-secret-key-change-in-production')
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///team_tryouts.db'
|
||||
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
|
||||
if not app.config['SECRET_KEY']:
|
||||
raise RuntimeError('SECRET_KEY environment variable must be set for security')
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'sqlite:///team_tryouts.db')
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
app.config['WTF_CSRF_ENABLED'] = True
|
||||
|
||||
# Secure session cookie settings
|
||||
app.config['SESSION_COOKIE_SECURE'] = os.getenv('SESSION_COOKIE_SECURE', 'true').lower() == 'true'
|
||||
app.config['SESSION_COOKIE_HTTPONLY'] = True
|
||||
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
|
||||
app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour session timeout
|
||||
|
||||
db.init_app(app)
|
||||
login_manager.init_app(app)
|
||||
csrf.init_app(app)
|
||||
limiter.init_app(app)
|
||||
|
||||
from routes.auth import auth_bp
|
||||
from routes.tryouts import tryouts_bp
|
||||
@@ -69,6 +82,24 @@ def create_app():
|
||||
# Register custom Jinja filters
|
||||
app.jinja_env.filters['nl2br'] = nl2br
|
||||
|
||||
# Add security headers to all responses
|
||||
@app.after_request
|
||||
def add_security_headers(response):
|
||||
response.headers['X-Content-Type-Options'] = 'nosniff'
|
||||
response.headers['X-Frame-Options'] = 'DENY'
|
||||
response.headers['X-XSS-Protection'] = '1; mode=block'
|
||||
response.headers['Content-Security-Policy'] = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';"
|
||||
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
|
||||
return response
|
||||
|
||||
# Force HTTPS in production (when not in debug mode)
|
||||
@app.before_request
|
||||
def force_https():
|
||||
if not app.debug:
|
||||
if not request.is_secure and request.headers.get('X-Forwarded-Proto') != 'https':
|
||||
if os.getenv('FORCE_HTTPS', 'true').lower() == 'true':
|
||||
return redirect(request.url.replace('http://', 'https://'), code=301)
|
||||
|
||||
with app.app_context():
|
||||
import models
|
||||
from models import User, MatchParticipant
|
||||
@@ -101,4 +132,6 @@ def create_app():
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = create_app()
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
# Debug mode should only be enabled via environment variable for security
|
||||
debug_mode = os.environ.get('FLASK_DEBUG', 'false').lower() == 'true'
|
||||
app.run(debug=debug_mode, host='0.0.0.0', port=5000)
|
||||
Reference in New Issue
Block a user