Security Troubleshooting¶
This guide covers security-related issues, incident response, and security best practices for troubleshooting and resolving security problems in the Studio Platform.
🚨 Security Incident Response¶
Immediate Response Steps¶
- Isolate the System - Disconnect affected systems from the network
- Preserve Evidence - Don't modify or delete any logs or data
- Assess Impact - Determine scope and severity of the incident
- Notify Stakeholders - Alert security team and management
- Document Everything - Record all actions and findings
Security Incident Checklist¶
# 1. Check for unauthorized access
docker-compose exec backend python manage.py check_security
# 2. Review recent authentication logs
docker-compose logs backend | grep -i "login\|auth\|failed"
# 3. Check for suspicious activity
docker-compose exec backend python manage.py audit_recent_activity
# 4. Verify system integrity
docker-compose exec backend python manage.py integrity_check
# 5. Generate security report
docker-compose exec backend python manage.py security_report
🔐 Authentication Issues¶
Failed Login Attempts¶
Problem: Brute force attack detected¶
Symptoms: - Multiple failed login attempts - Locked user accounts - Unusual login patterns
Solutions:
-
Enable Rate Limiting
# settings.py REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ], 'DEFAULT_THROTTLE_RATES': { 'anon': '5/hour', 'user': '1000/hour' } } # Custom rate limiting for login LOGIN_RATE_LIMIT = '5/15m' # 5 attempts per 15 minutes -
Implement Account Lockout
# authentication.py from django.core.cache import cache from django.contrib.auth import authenticate def authenticate_with_lockout(request, username, password): cache_key = f"login_attempts_{username}" attempts = cache.get(cache_key, 0) if attempts >= 5: return None, "Account temporarily locked" user = authenticate(request, username=username, password=password) if user is None: cache.set(cache_key, attempts + 1, 900) # 15 minutes return None, f"Invalid credentials. {4 - attempts} attempts remaining" cache.delete(cache_key) return user, "Login successful" -
Monitor Suspicious Activity
# middleware.py class SecurityMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # Log failed authentication attempts if request.path == '/api/login/' and request.method == 'POST': self.log_login_attempt(request) return self.get_response(request) def log_login_attempt(self, request): ip_address = self.get_client_ip(request) username = request.POST.get('username', '') # Log to security monitoring SecurityLog.objects.create( event_type='login_attempt', ip_address=ip_address, username=username, user_agent=request.META.get('HTTP_USER_AGENT', ''), timestamp=timezone.now() )
Session Hijacking¶
Problem: Session security compromised¶
Symptoms: - Users logged in from unexpected locations - Session tokens being used by unauthorized users - Account activity from unknown IPs
Solutions:
-
Implement Secure Session Management
-
IP-Based Session Validation
# middleware.py class SessionSecurityMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): if request.user.is_authenticated: session_ip = request.session.get('login_ip') current_ip = self.get_client_ip(request) if session_ip and session_ip != current_ip: # Log out user and notify auth.logout(request) self.notify_suspicious_activity(request, session_ip, current_ip) return self.get_response(request) def get_client_ip(self, request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: return x_forwarded_for.split(',')[0] return request.META.get('REMOTE_ADDR') -
Multi-Factor Authentication
# mfa.py import pyotp import qrcode from io import BytesIO import base64 class MFAService: @staticmethod def generate_secret(user): return pyotp.random_base32() @staticmethod def generate_qr_code(user, secret): totp_uri = pyotp.totp.TOTP(secret).provisioning_uri( name=user.email, issuer_name="Studio Platform" ) qr = qrcode.QRCode(version=1, box_size=10, border=5) qr.add_data(totp_uri) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") buffer = BytesIO() img.save(buffer, format='PNG') return base64.b64encode(buffer.getvalue()).decode() @staticmethod def verify_token(secret, token): totp = pyotp.TOTP(secret) return totp.verify(token, valid_window=1)
🛡️ Data Protection Issues¶
Data Leakage¶
Problem: Sensitive data exposed¶
Symptoms: - Sensitive information in logs - Data accessible without authentication - Information in error messages
Solutions:
-
Implement Data Masking
# utils.py import re def mask_sensitive_data(data): """Mask sensitive information in logs and responses""" if isinstance(data, str): # Mask email addresses data = re.sub(r'([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})', r'\1***@\2', data) # Mask phone numbers data = re.sub(r'(\d{3})\d{3}(\d{4})', r'\1***\2', data) # Mask credit card numbers data = re.sub(r'(\d{4})\d{8,12}(\d{4})', r'\1************\2', data) # Mask API keys data = re.sub(r'(api[_-]?key[_-]?[=:]?)[\w-]{20,}', r'\1***MASKED***', data, flags=re.IGNORECASE) return data # Usage in logging import logging class SecureFormatter(logging.Formatter): def format(self, record): message = super().format(record) return mask_sensitive_data(message) -
Secure Error Handling
# views.py from django.http import JsonResponse import logging logger = logging.getLogger(__name__) def handle_api_error(request, error): """Handle API errors without exposing sensitive information""" # Log full error details logger.error(f"API Error: {str(error)}", exc_info=True, extra={ 'request': request, 'user': request.user.id if request.user.is_authenticated else None }) # Return generic error to client return JsonResponse({ 'error': 'An internal error occurred', 'error_code': 'INTERNAL_ERROR', 'timestamp': timezone.now().isoformat() }, status=500) -
Data Encryption at Rest
# encryption.py from cryptography.fernet import Fernet import base64 import os class DataEncryption: def __init__(self): self.key = os.environ.get('ENCRYPTION_KEY') if not self.key: self.key = Fernet.generate_key().decode() self.cipher = Fernet(self.key.encode()) def encrypt(self, data): """Encrypt sensitive data""" if isinstance(data, str): data = data.encode() encrypted = self.cipher.encrypt(data) return base64.b64encode(encrypted).decode() def decrypt(self, encrypted_data): """Decrypt sensitive data""" if isinstance(encrypted_data, str): encrypted_data = base64.b64decode(encrypted_data.encode()) decrypted = self.cipher.decrypt(encrypted_data) return decrypted.decode() # Usage in models from django.db import models class EncryptedField(models.TextField): def __init__(self, *args, **kwargs): kwargs['blank'] = True super().__init__(*args, **kwargs) def from_db_value(self, value, expression, connection): if value is None: return value encryption = DataEncryption() return encryption.decrypt(value) def to_python(self, value): if value is None: return value if isinstance(value, str): return value return str(value) def get_prep_value(self, value): if value is None: return value encryption = DataEncryption() return encryption.encrypt(value)
Unauthorized Data Access¶
Problem: Users accessing data they shouldn't see¶
Symptoms: - Data visible to unauthorized users - API endpoints returning sensitive data - Permission bypass attempts
Solutions:
-
Implement Row-Level Security
# permissions.py from rest_framework.permissions import BasePermission class IsOwnerOrReadOnly(BasePermission): def has_object_permission(self, request, view, obj): if request.method in ['GET', 'HEAD', 'OPTIONS']: return True return obj.owner == request.user class ComplianceDataPermission(BasePermission): def has_permission(self, request, view): if not request.user.is_authenticated: return False # Check if user has access to the requested compliance framework framework_id = view.kwargs.get('framework_id') if framework_id: return request.user.has_perm('compliance.view_framework', framework_id) return True -
Data Access Auditing
# models.py from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class DataAccessLog(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) action = models.CharField(max_length=50) # 'view', 'edit', 'delete' resource_type = models.CharField(max_length=50) resource_id = models.CharField(max_length=100) ip_address = models.GenericIPAddressField() user_agent = models.TextField() timestamp = models.DateTimeField(auto_now_add=True) success = models.BooleanField(default=True) class Meta: indexes = [ models.Index(fields=['user', 'timestamp']), models.Index(fields=['resource_type', 'resource_id']), ] # middleware.py class DataAccessMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) # Log data access for API endpoints if request.path.startswith('/api/') and request.method in ['GET', 'PUT', 'DELETE']: self.log_data_access(request, response) return response def log_data_access(self, request, response): if request.user.is_authenticated and response.status_code < 400: DataAccessLog.objects.create( user=request.user, action=self.get_action_from_method(request.method), resource_type=self.get_resource_type(request.path), resource_id=self.get_resource_id(request.path), ip_address=self.get_client_ip(request), user_agent=request.META.get('HTTP_USER_AGENT', ''), success=response.status_code < 400 )
🔍 Security Monitoring¶
Intrusion Detection¶
Problem: Detecting security breaches¶
Symptoms: - Unusual system behavior - Suspicious network traffic - Anomalous user activity
Solutions:
-
Implement Security Monitoring
# monitoring.py import logging from django.core.cache import cache from datetime import datetime, timedelta class SecurityMonitor: def __init__(self): self.logger = logging.getLogger('security') def detect_anomalies(self, request): anomalies = [] # Check for unusual IP addresses if self.is_suspicious_ip(request): anomalies.append('suspicious_ip') # Check for rapid requests if self.is_rapid_requests(request): anomalies.append('rapid_requests') # Check for unusual user agent if self.is_unusual_user_agent(request): anomalies.append('unusual_user_agent') if anomalies: self.log_security_event(request, anomalies) return True return False def is_suspicious_ip(self, request): ip = self.get_client_ip(request) cache_key = f"ip_activity_{ip}" activity = cache.get(cache_key, {'count': 0, 'first_seen': datetime.now()}) activity['count'] += 1 cache.set(cache_key, activity, 3600) # 1 hour # Flag if more than 1000 requests per hour return activity['count'] > 1000 def is_rapid_requests(self, request): user_id = request.user.id if request.user.is_authenticated else None cache_key = f"rapid_requests_{user_id or self.get_client_ip(request)}" recent_requests = cache.get(cache_key, []) now = datetime.now() # Clean old requests (older than 1 minute) recent_requests = [req_time for req_time in recent_requests if now - req_time < timedelta(minutes=1)] recent_requests.append(now) cache.set(cache_key, recent_requests, 60) # Flag if more than 60 requests per minute return len(recent_requests) > 60 def log_security_event(self, request, anomalies): self.logger.warning( f"Security anomalies detected: {', '.join(anomalies)}", extra={ 'ip_address': self.get_client_ip(request), 'user': request.user.id if request.user.is_authenticated else None, 'path': request.path, 'method': request.method, 'user_agent': request.META.get('HTTP_USER_AGENT', ''), 'anomalies': anomalies } ) -
Automated Threat Response
# threat_response.py class ThreatResponseSystem: def __init__(self): self.blocked_ips = set() self.suspicious_users = set() def handle_threat(self, threat_type, details): if threat_type == 'brute_force': self.block_ip(details['ip_address']) elif threat_type == 'suspicious_activity': self.flag_user(details['user_id']) elif threat_type == 'data_breach_attempt': self.trigger_emergency_response(details) def block_ip(self, ip_address): """Block IP address at firewall level""" self.blocked_ips.add(ip_address) # Add to firewall rules os.system(f"iptables -A INPUT -s {ip_address} -j DROP") # Log the blocking action logging.warning(f"IP address {ip_address} blocked due to suspicious activity") def flag_user(self, user_id): """Flag user account for review""" self.suspicious_users.add(user_id) # Require additional authentication User.objects.filter(id=user_id).update( requires_mfa=True, is_active=False # Temporarily disable ) # Notify security team self.notify_security_team(f"User {user_id} flagged for suspicious activity") def trigger_emergency_response(self, details): """Trigger emergency security response""" # Block all access temporarily os.system("iptables -A INPUT -j DROP") # Notify all administrators self.notify_all_admins("EMERGENCY: Potential data breach detected") # Start incident response procedures self.start_incident_response()
🔧 Security Configuration Issues¶
SSL/TLS Problems¶
Problem: SSL/TLS configuration issues¶
Symptoms: - Certificate errors - Mixed content warnings - Insecure connection warnings
Solutions:
-
Fix SSL Configuration
# nginx.conf server { listen 443 ssl http2; listen [::]:443 ssl http2; # SSL configuration ssl_certificate /etc/ssl/certs/studio.crt; ssl_certificate_key /etc/ssl/private/studio.key; # Strong SSL configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # HSTS add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Other security headers add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "strict-origin-when-cross-origin"; } -
Automated Certificate Management
#!/bin/bash # cert-renewal.sh # Check certificate expiration cert_file="/etc/ssl/certs/studio.crt" expiration_date=$(openssl x509 -enddate -noout -in "$cert_file" | cut -d= -f2) expiration_timestamp=$(date -d "$expiration_date" +%s) current_timestamp=$(date +%s) days_until_expiration=$(( (expiration_timestamp - current_timestamp) / 86400 )) # Renew if expiring within 30 days if [ $days_until_expiration -lt 30 ]; then echo "Certificate expiring in $days_until_expiration days. Renewing..." certbot renew --quiet # Reload nginx docker-compose exec nginx nginx -s reload echo "Certificate renewed and nginx reloaded." else echo "Certificate is valid for $days_until_expiration more days." fi
Security Headers¶
Problem: Missing security headers¶
Symptoms: - Vulnerable to XSS attacks - Clickjacking vulnerabilities - Content type sniffing issues
Solutions:
- Implement Security Headers Middleware
# middleware.py class SecurityHeadersMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) # Add security headers response['X-Frame-Options'] = 'DENY' response['X-Content-Type-Options'] = 'nosniff' response['X-XSS-Protection'] = '1; mode=block' response['Referrer-Policy'] = 'strict-origin-when-cross-origin' response['Permissions-Policy'] = 'geolocation=(), microphone=(), camera=()' # CSP header response['Content-Security-Policy'] = ( "default-src 'self'; " "script-src 'self' 'unsafe-inline'; " "style-src 'self' 'unsafe-inline'; " "img-src 'self' data: https:; " "font-src 'self'; " "connect-src 'self'; " "frame-ancestors 'none';" ) return response
📊 Security Auditing¶
Regular Security Checks¶
Problem: Identifying security vulnerabilities¶
Symptoms: - Unknown security gaps - Outdated dependencies - Misconfigured permissions
Solutions:
-
Automated Security Scanning
# security_audit.py import subprocess import json from datetime import datetime class SecurityAuditor: def __init__(self): self.findings = [] def run_vulnerability_scan(self): """Run vulnerability scanner on dependencies""" try: result = subprocess.run( ['safety', 'check', '--json'], capture_output=True, text=True ) if result.stdout: vulnerabilities = json.loads(result.stdout) for vuln in vulnerabilities: self.add_finding( 'vulnerability', f"Dependency {vuln['package']} has vulnerability: {vuln['advisory']}", severity=vuln.get('vulnerability', 'medium') ) except Exception as e: self.add_finding('error', f"Vulnerability scan failed: {str(e)}") def check_configuration_security(self): """Check for security configuration issues""" # Check debug mode if settings.DEBUG: self.add_finding('configuration', 'DEBUG mode is enabled in production', 'high') # Check secret key if settings.SECRET_KEY == 'your-secret-key': self.add_finding('configuration', 'Default SECRET_KEY is being used', 'critical') # Check database settings if settings.DATABASES['default']['PASSWORD'] == 'password': self.add_finding('configuration', 'Default database password is being used', 'critical') def check_file_permissions(self): """Check file permissions for security""" import os import stat sensitive_files = [ '/app/.env', '/app/settings.py', '/app/requirements.txt' ] for file_path in sensitive_files: if os.path.exists(file_path): file_stat = os.stat(file_path) mode = file_stat.st_mode # Check if file is world-readable if mode & stat.S_IROTH: self.add_finding('permissions', f'File {file_path} is world-readable', 'medium') def add_finding(self, category, description, severity='medium'): self.findings.append({ 'category': category, 'description': description, 'severity': severity, 'timestamp': datetime.now().isoformat() }) def generate_report(self): """Generate security audit report""" return { 'scan_date': datetime.now().isoformat(), 'total_findings': len(self.findings), 'findings_by_severity': { 'critical': len([f for f in self.findings if f['severity'] == 'critical']), 'high': len([f for f in self.findings if f['severity'] == 'high']), 'medium': len([f for f in self.findings if f['severity'] == 'medium']), 'low': len([f for f in self.findings if f['severity'] == 'low']) }, 'findings': self.findings } # Usage auditor = SecurityAuditor() auditor.run_vulnerability_scan() auditor.check_configuration_security() auditor.check_file_permissions() report = auditor.generate_report() print(json.dumps(report, indent=2)) -
Security Compliance Check
# compliance_check.py class SecurityComplianceChecker: def __init__(self): self.compliance_standards = { 'OWASP': self.check_owasp_compliance, 'SOC2': self.check_soc2_compliance, 'ISO27001': self.check_iso27001_compliance } def check_owasp_compliance(self): """Check OWASP Top 10 compliance""" checks = { 'A01_Broken_Access_Control': self.check_access_control, 'A02_Cryptographic_Failures': self.check_cryptography, 'A03_Injection': self.check_injection_protection, 'A04_Insecure_Design': self.check_secure_design, 'A05_Security_Misconfiguration': self.check_security_configuration, 'A06_Vulnerable_Components': self.check_vulnerable_components, 'A07_Identification_Authentication_Failures': self.check_authentication, 'A08_Software_Data_Integrity_Failures': self.check_integrity, 'A09_Security_Logging_Monitoring': self.check_logging_monitoring, 'A10_Server_Side_Request_Forgery': self.check_ssrf_protection } results = {} for check_name, check_func in checks.items(): results[check_name] = check_func() return results def check_access_control(self): """Check for proper access control""" findings = [] # Check for default admin credentials if User.objects.filter(username='admin', is_superuser=True).exists(): findings.append('Default admin account exists') # Check for unprotected admin endpoints try: response = requests.get('http://localhost:8000/admin/', timeout=5) if response.status_code == 200: findings.append('Admin interface is accessible without authentication') except: pass return findings def check_cryptography(self): """Check for proper cryptographic implementation""" findings = [] # Check for weak encryption if 'DES' in open('/app/settings.py').read(): findings.append('Weak encryption algorithm (DES) found in configuration') # Check for hardcoded secrets if 'SECRET_KEY = ' in open('/app/settings.py').read() and 'your-secret-key' in open('/app/settings.py').read(): findings.append('Hardcoded secret key found') return findings
Security Monitoring
Implement continuous security monitoring with automated alerts for suspicious activities and configuration changes.
Incident Response
Have a documented incident response plan and conduct regular drills to ensure team readiness for security incidents.
Regular Audits
Schedule regular security audits and penetration testing to identify vulnerabilities before they can be exploited.