fix(audit): durcir les validations de securite

This commit is contained in:
GGThed
2026-08-17 13:51:37 -04:00
parent 06508cc7d6
commit f84cb4e3b6
5 changed files with 149 additions and 19 deletions
+33 -17
View File
@@ -6,7 +6,7 @@ This script performs pre-deployment security checks to validate:
- Debug mode status
- HTTPS configuration
- Dependency vulnerabilities
- Database connectivity
- Required database configuration
Usage:
python security_scan.py [--url http://localhost:5000]
@@ -19,6 +19,10 @@ import subprocess
import sys
import urllib.request
from datetime import datetime
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[2]
REQUIREMENTS_FILE = PROJECT_ROOT / 'requirements.txt'
def check_environment():
@@ -31,8 +35,8 @@ def check_environment():
print('1. ENVIRONMENT VARIABLES CHECK')
print('=' * 60)
critical_vars = ['SECRET_KEY']
recommended_vars = ['DATABASE_URL', 'CORS_ALLOWED_ORIGINS']
critical_vars = ['SECRET_KEY', 'DATABASE_URL']
recommended_vars = ['CORS_ALLOWED_ORIGINS']
all_ok = True
for var in critical_vars:
@@ -58,7 +62,8 @@ def check_environment():
# Check FLASK_DEBUG
debug = os.getenv('FLASK_DEBUG', 'false').lower()
if debug == 'true':
print('[WARN] FLASK_DEBUG is enabled! Should be disabled in production.')
print('[FAIL] FLASK_DEBUG is enabled! It must be disabled in production.')
all_ok = False
else:
print('[OK] FLASK_DEBUG is disabled')
@@ -91,10 +96,11 @@ def check_https_headers(url):
all_ok = True
try:
# Create a context that doesn't verify SSL (for local testing)
# Keep the default certificate and hostname verification. A scanner
# that accepts an invalid certificate can validate headers while the
# transport itself is impersonated. Local runs without TLS should use
# http:// explicitly or opt out with --skip-http.
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
req = urllib.request.Request(url, method='HEAD')
@@ -148,9 +154,9 @@ def check_https_headers(url):
all_ok = False
except urllib.error.URLError as e:
print(f'[SKIP] Cannot connect to {url}: {e.reason}')
print('[SKIP] Run with --url <application_url> to check headers')
return True # Not a failure, just can't check
print(f'[FAIL] Cannot connect to {url}: {e.reason}')
print('[INFO] Use --skip-http only when the live check is intentionally out of scope.')
return False
return all_ok
@@ -167,7 +173,15 @@ def check_dependencies():
try:
result = subprocess.run(
[sys.executable, '-m', 'pip_audit', '--format', 'json'],
[
sys.executable,
'-m',
'pip_audit',
'--requirement',
str(REQUIREMENTS_FILE),
'--format',
'json',
],
capture_output=True,
text=True,
timeout=60,
@@ -195,14 +209,16 @@ def check_dependencies():
if result.stdout:
print(f'[INFO] {result.stdout.strip()}')
if result.stderr:
print(f'[WARN] {result.stderr.strip()}')
return True
print(f'[FAIL] {result.stderr.strip()}')
else:
print(f'[FAIL] pip-audit exited with status {result.returncode}.')
return False
except FileNotFoundError:
print('[SKIP] pip-audit not installed. Run: pip install pip-audit')
return True
print('[FAIL] pip-audit not installed. Run: pip install pip-audit')
return False
except subprocess.TimeoutExpired:
print('[WARN] pip-audit timed out')
return True
print('[FAIL] pip-audit timed out')
return False
def check_file_permissions():