# Know Foolery - Detailed Security Implementation Guidelines ## Authentication & Authorization ### OAuth 2.0/OIDC Implementation - See [Zitadel Integration Guidelines](zitadel-guidelines.md) ### Session Management ```go // Secure session management package session import ( "context" "crypto/rand" "crypto/sha256" "encoding/hex" "fmt" "time" "github.com/go-redis/redis/v8" ) type SessionManager struct { redis *redis.Client entropy int maxAge time.Duration secureCookie bool } type Session struct { ID string `json:"id"` UserID string `json:"user_id"` CreatedAt time.Time `json:"created_at"` LastSeen time.Time `json:"last_seen"` IPAddress string `json:"ip_address"` UserAgent string `json:"user_agent"` DeviceID string `json:"device_id,omitempty"` Roles []string `json:"roles"` MFAVerified bool `json:"mfa_verified"` } func NewSessionManager(redis *redis.Client, secureCookie bool) *SessionManager { return &SessionManager{ redis: redis, entropy: 32, // 256 bits of entropy maxAge: 24 * time.Hour, secureCookie: secureCookie, } } func (sm *SessionManager) CreateSession(ctx context.Context, userID, ipAddress, userAgent string, roles []string, mfaVerified bool) (*Session, error) { // Generate cryptographically secure session ID sessionID, err := sm.generateSecureSessionID() if err != nil { return nil, fmt.Errorf("failed to generate session ID: %w", err) } session := &Session{ ID: sessionID, UserID: userID, CreatedAt: time.Now(), LastSeen: time.Now(), IPAddress: ipAddress, UserAgent: userAgent, DeviceID: sm.generateDeviceFingerprint(ipAddress, userAgent), Roles: roles, MFAVerified: mfaVerified, } // Store session in Redis with expiration sessionKey := fmt.Sprintf("session:%s", sessionID) sessionData, err := json.Marshal(session) if err != nil { return nil, fmt.Errorf("failed to marshal session: %w", err) } err = sm.redis.SetEX(ctx, sessionKey, sessionData, sm.maxAge).Err() if err != nil { return nil, fmt.Errorf("failed to store session: %w", err) } // Store user session mapping for concurrent session limiting userSessionKey := fmt.Sprintf("user_sessions:%s", userID) sm.redis.SAdd(ctx, userSessionKey, sessionID) sm.redis.Expire(ctx, userSessionKey, sm.maxAge) return session, nil } func (sm *SessionManager) GetSession(ctx context.Context, sessionID string) (*Session, error) { sessionKey := fmt.Sprintf("session:%s", sessionID) sessionData, err := sm.redis.Get(ctx, sessionKey).Result() if err == redis.Nil { return nil, fmt.Errorf("session not found") } else if err != nil { return nil, fmt.Errorf("failed to retrieve session: %w", err) } var session Session err = json.Unmarshal([]byte(sessionData), &session) if err != nil { return nil, fmt.Errorf("failed to unmarshal session: %w", err) } return &session, nil } func (sm *SessionManager) IsValidSession(sessionID, userID string) bool { ctx := context.Background() session, err := sm.GetSession(ctx, sessionID) if err != nil { return false } // Check if session belongs to the correct user if session.UserID != userID { return false } // Update last seen timestamp session.LastSeen = time.Now() sm.updateSession(ctx, session) return true } func (sm *SessionManager) InvalidateSession(ctx context.Context, sessionID string) error { session, err := sm.GetSession(ctx, sessionID) if err != nil { return err } // Remove from Redis sessionKey := fmt.Sprintf("session:%s", sessionID) sm.redis.Del(ctx, sessionKey) // Remove from user sessions set userSessionKey := fmt.Sprintf("user_sessions:%s", session.UserID) sm.redis.SRem(ctx, userSessionKey, sessionID) return nil } func (sm *SessionManager) InvalidateAllUserSessions(ctx context.Context, userID string) error { userSessionKey := fmt.Sprintf("user_sessions:%s", userID) sessionIDs, err := sm.redis.SMembers(ctx, userSessionKey).Result() if err != nil { return err } // Remove all sessions for _, sessionID := range sessionIDs { sessionKey := fmt.Sprintf("session:%s", sessionID) sm.redis.Del(ctx, sessionKey) } // Clear user sessions set sm.redis.Del(ctx, userSessionKey) return nil } func (sm *SessionManager) generateSecureSessionID() (string, error) { bytes := make([]byte, sm.entropy) _, err := rand.Read(bytes) if err != nil { return "", err } // Hash the random bytes for additional security hash := sha256.Sum256(bytes) return hex.EncodeToString(hash[:]), nil } func (sm *SessionManager) generateDeviceFingerprint(ipAddress, userAgent string) string { data := fmt.Sprintf("%s:%s", ipAddress, userAgent) hash := sha256.Sum256([]byte(data)) return hex.EncodeToString(hash[:16]) // 128-bit fingerprint } func (sm *SessionManager) updateSession(ctx context.Context, session *Session) error { sessionKey := fmt.Sprintf("session:%s", session.ID) sessionData, err := json.Marshal(session) if err != nil { return err } return sm.redis.SetEX(ctx, sessionKey, sessionData, sm.maxAge).Err() } ``` ## Input Validation & Sanitization ### Comprehensive Input Validation ```go // Input validation and sanitization framework package validation import ( "fmt" "html" "regexp" "strings" "unicode" "github.com/go-playground/validator/v10" ) type InputValidator struct { validator *validator.Validate rules map[string]*ValidationRule } type ValidationRule struct { MaxLength int MinLength int Pattern *regexp.Regexp AllowedChars *regexp.Regexp Sanitizer func(string) string } func NewInputValidator() *InputValidator { v := validator.New() // Register custom validations v.RegisterValidation("alphanum_space", validateAlphanumSpace) v.RegisterValidation("no_html", validateNoHTML) v.RegisterValidation("safe_text", validateSafeText) iv := &InputValidator{ validator: v, rules: make(map[string]*ValidationRule), } iv.setupValidationRules() return iv } func (iv *InputValidator) setupValidationRules() { // Player name validation iv.rules["player_name"] = &ValidationRule{ MaxLength: 50, MinLength: 2, AllowedChars: regexp.MustCompile(`^[a-zA-Z0-9\s\-_.]+$`), Sanitizer: iv.sanitizePlayerName, } // Answer validation iv.rules["answer"] = &ValidationRule{ MaxLength: 500, MinLength: 1, AllowedChars: regexp.MustCompile(`^[a-zA-Z0-9\s\-_.,'!?()]+$`), Sanitizer: iv.sanitizeAnswer, } // Question text validation (admin only) iv.rules["question_text"] = &ValidationRule{ MaxLength: 1000, MinLength: 10, Sanitizer: iv.sanitizeQuestionText, } // Theme validation iv.rules["theme"] = &ValidationRule{ MaxLength: 100, MinLength: 2, AllowedChars: regexp.MustCompile(`^[a-zA-Z0-9\s\-_]+$`), Sanitizer: iv.sanitizeTheme, } } // Validate and sanitize input based on field type func (iv *InputValidator) ValidateAndSanitize(fieldType, input string) (string, error) { rule, exists := iv.rules[fieldType] if !exists { return "", fmt.Errorf("unknown field type: %s", fieldType) } // Basic length validation if len(input) < rule.MinLength { return "", fmt.Errorf("input too short: minimum %d characters", rule.MinLength) } if len(input) > rule.MaxLength { return "", fmt.Errorf("input too long: maximum %d characters", rule.MaxLength) } // Character validation if rule.AllowedChars != nil && !rule.AllowedChars.MatchString(input) { return "", fmt.Errorf("input contains invalid characters") } // Sanitize input sanitized := input if rule.Sanitizer != nil { sanitized = rule.Sanitizer(input) } return sanitized, nil } // Sanitization functions func (iv *InputValidator) sanitizePlayerName(input string) string { // Remove HTML entities and tags sanitized := html.EscapeString(input) // Trim whitespace sanitized = strings.TrimSpace(sanitized) // Remove multiple consecutive spaces spaceRegex := regexp.MustCompile(`\s+`) sanitized = spaceRegex.ReplaceAllString(sanitized, " ") return sanitized } func (iv *InputValidator) sanitizeAnswer(input string) string { // HTML escape sanitized := html.EscapeString(input) // Trim and normalize whitespace sanitized = strings.TrimSpace(sanitized) // Convert to lowercase for comparison sanitized = strings.ToLower(sanitized) // Remove extra punctuation but keep essential ones punctRegex := regexp.MustCompile(`[^\w\s\-'.]`) sanitized = punctRegex.ReplaceAllString(sanitized, "") return sanitized } func (iv *InputValidator) sanitizeQuestionText(input string) string { // More permissive sanitization for question text sanitized := html.EscapeString(input) sanitized = strings.TrimSpace(sanitized) // Remove potential script content scriptRegex := regexp.MustCompile(`(?i)]*>.*?`) sanitized = scriptRegex.ReplaceAllString(sanitized, "") return sanitized } func (iv *InputValidator) sanitizeTheme(input string) string { sanitized := html.EscapeString(input) sanitized = strings.TrimSpace(sanitized) // Capitalize first letter of each word words := strings.Fields(sanitized) for i, word := range words { if len(word) > 0 { words[i] = strings.ToUpper(string(word[0])) + strings.ToLower(word[1:]) } } return strings.Join(words, " ") } // Custom validation functions func validateAlphanumSpace(fl validator.FieldLevel) bool { str := fl.Field().String() for _, r := range str { if !unicode.IsLetter(r) && !unicode.IsNumber(r) && !unicode.IsSpace(r) && r != '-' && r != '_' && r != '.' { return false } } return true } func validateNoHTML(fl validator.FieldLevel) bool { str := fl.Field().String() return !strings.Contains(str, "<") && !strings.Contains(str, ">") } func validateSafeText(fl validator.FieldLevel) bool { str := fl.Field().String() // Check for potential XSS patterns dangerousPatterns := []string{ "javascript:", "data:", "vbscript:", "on\\w+\\s*=", " int64(limit.Requests) { return c.Status(429).JSON(fiber.Map{ "error": true, "message": "Rate limit exceeded", "retry_after": int(limit.Window.Seconds()), }) } // Add rate limit headers c.Set("X-RateLimit-Limit", fmt.Sprintf("%d", limit.Requests)) c.Set("X-RateLimit-Remaining", fmt.Sprintf("%d", limit.Requests-int(current))) c.Set("X-RateLimit-Reset", fmt.Sprintf("%d", time.Now().Add(limit.Window).Unix())) return c.Next() } } ``` ## Game Integrity & Anti-Cheating ### Server-Side Validation ```go // Game integrity and anti-cheating measures package integrity import ( "context" "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" "math" "time" ) type GameIntegrityService struct { secretKey []byte auditLogger *AuditLogger anomalyDetector *AnomalyDetector } type GameState struct { SessionID string `json:"session_id"` PlayerID string `json:"player_id"` QuestionID string `json:"question_id"` StartTime time.Time `json:"start_time"` AttemptsUsed int `json:"attempts_used"` HintsUsed int `json:"hints_used"` Score int `json:"score"` ServerHash string `json:"server_hash"` } type AnswerSubmission struct { SessionID string `json:"session_id"` QuestionID string `json:"question_id"` Answer string `json:"answer"` AttemptNum int `json:"attempt_num"` TimeTaken time.Duration `json:"time_taken"` ClientHash string `json:"client_hash,omitempty"` Timestamp time.Time `json:"timestamp"` } type IntegrityCheck struct { IsValid bool `json:"is_valid"` Violations []string `json:"violations"` RiskScore float64 `json:"risk_score"` Action string `json:"action"` // allow, warn, block } func NewGameIntegrityService(secretKey []byte, auditLogger *AuditLogger) *GameIntegrityService { return &GameIntegrityService{ secretKey: secretKey, auditLogger: auditLogger, anomalyDetector: NewAnomalyDetector(), } } func (gis *GameIntegrityService) ValidateAnswerSubmission(ctx context.Context, submission *AnswerSubmission, gameState *GameState) (*IntegrityCheck, error) { check := &IntegrityCheck{ IsValid: true, Violations: []string{}, RiskScore: 0.0, } // 1. Validate timing if err := gis.validateTiming(submission, gameState, check); err != nil { return check, err } // 2. Validate sequence if err := gis.validateSequence(submission, gameState, check); err != nil { return check, err } // 3. Validate game state hash if err := gis.validateGameStateHash(submission, gameState, check); err != nil { return check, err } // 4. Check for behavioral anomalies if err := gis.checkBehavioralAnomalies(ctx, submission, check); err != nil { return check, err } // 5. Calculate final risk score and action gis.calculateRiskAndAction(check) // 6. Log integrity check results gis.auditLogger.LogSecurityEvent("game_integrity_check", submission.SessionID, "", "info", map[string]interface{}{ "session_id": submission.SessionID, "question_id": submission.QuestionID, "risk_score": check.RiskScore, "violations": check.Violations, "action": check.Action, }) return check, nil } func (gis *GameIntegrityService) validateTiming(submission *AnswerSubmission, gameState *GameState, check *IntegrityCheck) error { // Minimum time check (prevent instant answers) minTime := 2 * time.Second if submission.TimeTaken < minTime { check.Violations = append(check.Violations, "answer_too_fast") check.RiskScore += 0.3 } // Maximum time check (session timeout) maxTime := 30 * time.Minute totalTime := time.Since(gameState.StartTime) if totalTime > maxTime { check.Violations = append(check.Violations, "session_expired") check.RiskScore += 0.8 check.IsValid = false } // Check for time manipulation if submission.Timestamp.Before(gameState.StartTime) { check.Violations = append(check.Violations, "timestamp_manipulation") check.RiskScore += 0.5 } return nil } func (gis *GameIntegrityService) validateSequence(submission *AnswerSubmission, gameState *GameState, check *IntegrityCheck) error { // Validate attempt number if submission.AttemptNum != gameState.AttemptsUsed+1 { check.Violations = append(check.Violations, "invalid_attempt_sequence") check.RiskScore += 0.4 } // Validate attempt limits if submission.AttemptNum > 3 { check.Violations = append(check.Violations, "exceeded_attempt_limit") check.RiskScore += 0.6 check.IsValid = false } // Validate question sequence if submission.QuestionID != gameState.QuestionID { check.Violations = append(check.Violations, "question_mismatch") check.RiskScore += 0.5 check.IsValid = false } return nil } func (gis *GameIntegrityService) validateGameStateHash(submission *AnswerSubmission, gameState *GameState, check *IntegrityCheck) error { // Calculate expected hash expectedHash := gis.calculateGameStateHash(gameState) if gameState.ServerHash != expectedHash { check.Violations = append(check.Violations, "game_state_tampering") check.RiskScore += 0.7 check.IsValid = false } return nil } func (gis *GameIntegrityService) checkBehavioralAnomalies(ctx context.Context, submission *AnswerSubmission, check *IntegrityCheck) error { // Check answer patterns anomalies := gis.anomalyDetector.DetectAnomalies(ctx, submission.SessionID, map[string]interface{}{ "time_taken": submission.TimeTaken.Seconds(), "answer_length": len(submission.Answer), "attempt_num": submission.AttemptNum, }) for _, anomaly := range anomalies { check.Violations = append(check.Violations, fmt.Sprintf("anomaly_%s", anomaly.Type)) check.RiskScore += anomaly.Severity } return nil } func (gis *GameIntegrityService) calculateRiskAndAction(check *IntegrityCheck) { // Apply penalties for multiple violations if len(check.Violations) > 1 { check.RiskScore += float64(len(check.Violations)) * 0.1 } // Determine action based on risk score switch { case check.RiskScore >= 0.8: check.Action = "block" check.IsValid = false case check.RiskScore >= 0.5: check.Action = "warn" default: check.Action = "allow" } } func (gis *GameIntegrityService) calculateGameStateHash(gameState *GameState) string { data := fmt.Sprintf("%s:%s:%s:%d:%d:%d:%d", gameState.SessionID, gameState.PlayerID, gameState.QuestionID, gameState.StartTime.Unix(), gameState.AttemptsUsed, gameState.HintsUsed, gameState.Score, ) h := hmac.New(sha256.New, gis.secretKey) h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) } func (gis *GameIntegrityService) UpdateGameState(gameState *GameState) { gameState.ServerHash = gis.calculateGameStateHash(gameState) } // Anomaly detection for behavioral patterns type AnomalyDetector struct { patterns map[string]*PatternTracker } type PatternTracker struct { Samples []float64 Mean float64 StdDev float64 SampleCount int } type Anomaly struct { Type string Severity float64 Details string } func NewAnomalyDetector() *AnomalyDetector { return &AnomalyDetector{ patterns: make(map[string]*PatternTracker), } } func (ad *AnomalyDetector) DetectAnomalies(ctx context.Context, sessionID string, metrics map[string]interface{}) []Anomaly { var anomalies []Anomaly for metricName, value := range metrics { if floatValue, ok := value.(float64); ok { if anomaly := ad.checkMetricAnomaly(sessionID, metricName, floatValue); anomaly != nil { anomalies = append(anomalies, *anomaly) } } } return anomalies } func (ad *AnomalyDetector) checkMetricAnomaly(sessionID, metricName string, value float64) *Anomaly { key := fmt.Sprintf("%s:%s", sessionID, metricName) tracker, exists := ad.patterns[key] if !exists { tracker = &PatternTracker{ Samples: []float64{}, } ad.patterns[key] = tracker } // Add sample tracker.Samples = append(tracker.Samples, value) tracker.SampleCount++ // Need at least 3 samples to detect anomalies if tracker.SampleCount < 3 { return nil } // Calculate statistics ad.updateStatistics(tracker) // Check for anomaly (z-score > 2) if tracker.StdDev > 0 { zScore := math.Abs(value-tracker.Mean) / tracker.StdDev if zScore > 2.0 { severity := math.Min(zScore/5.0, 0.3) // Cap at 0.3 return &Anomaly{ Type: metricName, Severity: severity, Details: fmt.Sprintf("z-score: %.2f", zScore), } } } return nil } func (ad *AnomalyDetector) updateStatistics(tracker *PatternTracker) { n := float64(len(tracker.Samples)) // Calculate mean sum := 0.0 for _, sample := range tracker.Samples { sum += sample } tracker.Mean = sum / n // Calculate standard deviation sumSquares := 0.0 for _, sample := range tracker.Samples { diff := sample - tracker.Mean sumSquares += diff * diff } tracker.StdDev = math.Sqrt(sumSquares / n) } ``` ## Security Monitoring & Incident Response ### Security Event Monitoring ```go // Security monitoring and incident response package security import ( "context" "encoding/json" "fmt" "time" ) type SecurityMonitor struct { alertManager *AlertManager incidentManager *IncidentManager auditLogger *AuditLogger redis *redis.Client } type SecurityEvent struct { ID string `json:"id"` Type string `json:"type"` Severity string `json:"severity"` UserID string `json:"user_id,omitempty"` IPAddress string `json:"ip_address"` UserAgent string `json:"user_agent,omitempty"` Timestamp time.Time `json:"timestamp"` Details map[string]interface{} `json:"details"` Context string `json:"context"` } type IncidentResponse struct { IncidentID string `json:"incident_id"` Action string `json:"action"` AutomatedActions []string `json:"automated_actions"` RequiresManualReview bool `json:"requires_manual_review"` Timestamp time.Time `json:"timestamp"` } func NewSecurityMonitor(alertManager *AlertManager, incidentManager *IncidentManager, auditLogger *AuditLogger, redis *redis.Client) *SecurityMonitor { return &SecurityMonitor{ alertManager: alertManager, incidentManager: incidentManager, auditLogger: auditLogger, redis: redis, } } func (sm *SecurityMonitor) ProcessSecurityEvent(ctx context.Context, event *SecurityEvent) (*IncidentResponse, error) { // Enrich event with additional context if err := sm.enrichSecurityEvent(ctx, event); err != nil { return nil, fmt.Errorf("failed to enrich security event: %w", err) } // Analyze threat level threatLevel := sm.analyzeThreatLevel(ctx, event) // Create incident response response := &IncidentResponse{ IncidentID: generateIncidentID(), Timestamp: time.Now(), AutomatedActions: []string{}, } // Execute automated response based on threat level switch threatLevel { case "critical": response.Action = "block_immediately" response.RequiresManualReview = true response.AutomatedActions = append(response.AutomatedActions, "block_user", "invalidate_sessions", "notify_security_team") sm.executeAutomatedResponse(ctx, event, response) case "high": response.Action = "temporary_restriction" response.RequiresManualReview = true response.AutomatedActions = append(response.AutomatedActions, "rate_limit_user", "require_additional_auth", "alert_security_team") sm.executeAutomatedResponse(ctx, event, response) case "medium": response.Action = "monitor_closely" response.RequiresManualReview = false response.AutomatedActions = append(response.AutomatedActions, "increase_logging", "flag_for_review") sm.executeAutomatedResponse(ctx, event, response) case "low": response.Action = "log_and_continue" response.RequiresManualReview = false response.AutomatedActions = append(response.AutomatedActions, "log_event") default: response.Action = "no_action" } // Log incident response sm.auditLogger.LogSecurityEvent("incident_response", event.UserID, event.IPAddress, "info", map[string]interface{}{ "incident_id": response.IncidentID, "original_event": event.Type, "threat_level": threatLevel, "response_action": response.Action, "automated_actions": response.AutomatedActions, }) return response, nil } func (sm *SecurityMonitor) enrichSecurityEvent(ctx context.Context, event *SecurityEvent) error { // Add geolocation data if geoData, err := sm.getGeolocation(event.IPAddress); err == nil { event.Details["geolocation"] = geoData } // Add user behavior history if event.UserID != "" { if userHistory, err := sm.getUserBehaviorHistory(ctx, event.UserID); err == nil { event.Details["user_history"] = userHistory } } // Add IP reputation data if reputation, err := sm.getIPReputation(event.IPAddress); err == nil { event.Details["ip_reputation"] = reputation } return nil } func (sm *SecurityMonitor) analyzeThreatLevel(ctx context.Context, event *SecurityEvent) string { score := 0 // Base severity score switch event.Severity { case "critical": score += 40 case "high": score += 30 case "medium": score += 20 case "low": score += 10 } // Event type scoring threatScores := map[string]int{ "brute_force_attack": 35, "sql_injection_attempt": 40, "xss_attempt": 30, "session_hijack": 35, "privilege_escalation": 40, "data_exfiltration": 45, "unusual_access_pattern": 20, "rate_limit_exceeded": 15, "authentication_failure": 10, "suspicious_user_agent": 15, "geo_anomaly": 25, } if typeScore, exists := threatScores[event.Type]; exists { score += typeScore } // User history factor if userHistory, exists := event.Details["user_history"].(map[string]interface{}); exists { if previousIncidents, ok := userHistory["incident_count"].(int); ok { score += previousIncidents * 5 } } // IP reputation factor if reputation, exists := event.Details["ip_reputation"].(map[string]interface{}); exists { if malicious, ok := reputation["is_malicious"].(bool); ok && malicious { score += 25 } if proxy, ok := reputation["is_proxy"].(bool); ok && proxy { score += 10 } } // Geographic anomaly if geoData, exists := event.Details["geolocation"].(map[string]interface{}); exists { if country, ok := geoData["country"].(string); ok { if sm.isHighRiskCountry(country) { score += 15 } } } // Convert score to threat level switch { case score >= 70: return "critical" case score >= 50: return "high" case score >= 30: return "medium" case score >= 15: return "low" default: return "minimal" } } func (sm *SecurityMonitor) executeAutomatedResponse(ctx context.Context, event *SecurityEvent, response *IncidentResponse) error { for _, action := range response.AutomatedActions { switch action { case "block_user": if event.UserID != "" { sm.blockUser(ctx, event.UserID, response.IncidentID) } case "invalidate_sessions": if event.UserID != "" { sm.invalidateUserSessions(ctx, event.UserID) } case "block_ip": sm.blockIP(ctx, event.IPAddress, time.Hour*24) // 24-hour block case "rate_limit_user": if event.UserID != "" { sm.applyRateLimit(ctx, event.UserID, time.Hour) // 1-hour rate limit } case "require_additional_auth": if event.UserID != "" { sm.requireAdditionalAuth(ctx, event.UserID) } case "notify_security_team": sm.notifySecurityTeam(event, response) case "alert_security_team": sm.alertSecurityTeam(event, response) case "increase_logging": sm.increaseLoggingLevel(event.UserID, event.IPAddress) case "flag_for_review": sm.flagForManualReview(event, response) } } return nil } func (sm *SecurityMonitor) blockUser(ctx context.Context, userID, incidentID string) error { // Add user to blocked list key := fmt.Sprintf("blocked_users:%s", userID) blockData := map[string]interface{}{ "blocked_at": time.Now().Unix(), "incident_id": incidentID, "reason": "automated_security_response", } blockJSON, _ := json.Marshal(blockData) return sm.redis.Set(ctx, key, blockJSON, 24*time.Hour).Err() } func (sm *SecurityMonitor) blockIP(ctx context.Context, ipAddress string, duration time.Duration) error { key := fmt.Sprintf("blocked_ips:%s", ipAddress) blockData := map[string]interface{}{ "blocked_at": time.Now().Unix(), "expires_at": time.Now().Add(duration).Unix(), "reason": "automated_security_response", } blockJSON, _ := json.Marshal(blockData) return sm.redis.Set(ctx, key, blockJSON, duration).Err() } func (sm *SecurityMonitor) applyRateLimit(ctx context.Context, userID string, duration time.Duration) error { key := fmt.Sprintf("rate_limit_strict:%s", userID) limitData := map[string]interface{}{ "limit": 5, // 5 requests per minute "window": 60, // 1 minute window "applied_at": time.Now().Unix(), } limitJSON, _ := json.Marshal(limitData) return sm.redis.Set(ctx, key, limitJSON, duration).Err() } func (sm *SecurityMonitor) notifySecurityTeam(event *SecurityEvent, response *IncidentResponse) { notification := map[string]interface{}{ "type": "security_incident", "severity": "critical", "incident_id": response.IncidentID, "event_type": event.Type, "user_id": event.UserID, "ip_address": event.IPAddress, "timestamp": event.Timestamp, "details": event.Details, } // Send to security team via multiple channels sm.alertManager.SendSlackAlert("#security-incidents", notification) sm.alertManager.SendPagerDutyAlert(notification) sm.alertManager.SendEmailAlert("security@knowfoolery.com", notification) } // Security health checks func (sm *SecurityMonitor) PerformSecurityHealthCheck(ctx context.Context) (*SecurityHealthStatus, error) { status := &SecurityHealthStatus{ Timestamp: time.Now(), Checks: make(map[string]CheckResult), } // Check authentication system status.Checks["auth_system"] = sm.checkAuthSystemHealth(ctx) // Check rate limiting status.Checks["rate_limiting"] = sm.checkRateLimitingHealth(ctx) // Check encryption services status.Checks["encryption"] = sm.checkEncryptionHealth(ctx) // Check security monitoring status.Checks["monitoring"] = sm.checkMonitoringHealth(ctx) // Check blocked IPs/users status.Checks["blocked_entities"] = sm.checkBlockedEntitiesHealth(ctx) // Calculate overall health status.OverallHealth = sm.calculateOverallHealth(status.Checks) return status, nil } type SecurityHealthStatus struct { Timestamp time.Time `json:"timestamp"` OverallHealth string `json:"overall_health"` Checks map[string]CheckResult `json:"checks"` } type CheckResult struct { Status string `json:"status"` // healthy, degraded, unhealthy Message string `json:"message"` Details map[string]interface{} `json:"details,omitempty"` } ``` This comprehensive security implementation ensures Know Foolery has robust protection against common threats while maintaining usability and performance. The security measures are layered and include proactive monitoring, automated incident response, and detailed audit trails for compliance and forensic analysis.