-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecurity_logger.py
More file actions
122 lines (106 loc) · 4.49 KB
/
Copy pathsecurity_logger.py
File metadata and controls
122 lines (106 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import logging
import os
from datetime import datetime
import json
from typing import Dict, Any, Optional
from fastapi import Request
# Configure security-specific logger
logger = logging.getLogger("security")
logger.setLevel(logging.INFO)
# Create a file handler for security logs
os.makedirs("logs", exist_ok=True)
security_log_file = os.path.join("logs", "security.log")
file_handler = logging.FileHandler(security_log_file)
# Create a formatter that obscures sensitive data
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
class SecurityLogger:
@staticmethod
def mask_sensitive_data(data: Dict[str, Any]) -> Dict[str, Any]:
"""Mask sensitive data in logs"""
SENSITIVE_FIELDS = {
"password", "token", "api_key", "secret", "credit_card",
"card_number", "cvv", "expiry", "access_token", "refresh_token"
}
masked_data = {}
for key, value in data.items():
if key.lower() in SENSITIVE_FIELDS:
masked_data[key] = "********"
elif isinstance(value, dict):
masked_data[key] = SecurityLogger.mask_sensitive_data(value)
elif isinstance(value, list):
masked_data[key] = [
SecurityLogger.mask_sensitive_data(item) if isinstance(item, dict) else item
for item in value
]
else:
masked_data[key] = value
return masked_data
@staticmethod
def log_login_attempt(username: str, ip_address: str, success: bool, user_agent: Optional[str] = None):
"""Log login attempts"""
security_event = {
"event_type": "login_attempt",
"timestamp": datetime.now().isoformat(),
"username": username,
"ip_address": ip_address,
"success": success,
"user_agent": user_agent
}
if success:
logger.info(f"Successful login: {username} from {ip_address}")
else:
logger.warning(f"Failed login attempt: {username} from {ip_address}")
logger.debug(json.dumps(security_event))
@staticmethod
def log_api_access(request: Request, user_id: str, endpoint: str):
"""Log API access"""
security_event = {
"event_type": "api_access",
"timestamp": datetime.now().isoformat(),
"user_id": user_id,
"ip_address": request.client.host,
"method": request.method,
"endpoint": endpoint,
"user_agent": request.headers.get("user-agent", "unknown")
}
logger.info(f"API access: {user_id} accessed {endpoint} from {request.client.host}")
logger.debug(json.dumps(security_event))
@staticmethod
def log_unauthorized_access(request: Request, endpoint: str):
"""Log unauthorized access attempts"""
security_event = {
"event_type": "unauthorized_access",
"timestamp": datetime.now().isoformat(),
"ip_address": request.client.host,
"method": request.method,
"endpoint": endpoint,
"user_agent": request.headers.get("user-agent", "unknown"),
"headers": dict(request.headers)
}
logger.warning(f"Unauthorized access attempt to {endpoint} from {request.client.host}")
logger.debug(json.dumps(SecurityLogger.mask_sensitive_data(security_event)))
@staticmethod
def log_security_event(event_type: str, details: Dict[str, Any], level: str = "info"):
"""Log a generic security event"""
security_event = {
"event_type": event_type,
"timestamp": datetime.now().isoformat(),
"details": details
}
masked_event = SecurityLogger.mask_sensitive_data(security_event)
if level == "info":
logger.info(f"Security event: {event_type}")
logger.debug(json.dumps(masked_event))
elif level == "warning":
logger.warning(f"Security warning: {event_type}")
logger.debug(json.dumps(masked_event))
elif level == "error":
logger.error(f"Security error: {event_type}")
logger.debug(json.dumps(masked_event))
elif level == "critical":
logger.critical(f"Critical security event: {event_type}")
logger.debug(json.dumps(masked_event))