# frozen_string_literal: true class ProcessWafAnalyticsJob < ApplicationJob queue_as :waf_analytics def perform(event_id:) event = Event.find(event_id) # Analyze event patterns analyze_traffic_patterns(event) analyze_geographic_distribution(event) analyze_attack_vectors(event) # Update global analytics cache update_analytics_cache rescue => e Rails.logger.error "Error processing WAF analytics: #{e.message}" Rails.logger.error e.backtrace.join("\n") end private def analyze_traffic_patterns(event) # Look for unusual traffic spikes recent_events = Event.where(timestamp: 5.minutes.ago..Time.current) # Use a default threshold since we no longer have project-specific thresholds threshold = 1000 # Default threshold if recent_events.count > threshold * 5 # High traffic detected - create an issue Issue.create!( title: "High Traffic Spike Detected", description: "Detected #{recent_events.count} requests in the last 5 minutes", severity: "medium", event_id: event.id, metadata: { event_count: recent_events.count, time_window: "5 minutes", threshold: threshold * 5 } ) end end def analyze_geographic_distribution(event) return unless event.has_geo_data? country_code = event.lookup_country return unless country_code.present? # Check if this country is unusual globally by joining through network ranges country_events = Event .joins("JOIN network_ranges ON events.ip_address <<= network_ranges.network") .where("network_ranges.country = ?", country_code) .where(timestamp: 1.hour.ago..Time.current) # If this is the first event from this country or unusual spike if country_events.count == 1 || country_events.count > 100 Rails.logger.info "Unusual geographic activity from #{country_code}" end end def analyze_attack_vectors(event) return unless event.blocked? # Analyze common attack patterns analyze_ip_reputation(event) analyze_user_agent_patterns(event) analyze_path_attacks(event) end def analyze_ip_reputation(event) return unless event.ip_address.present? # Count recent blocks from this IP recent_blocks = Event .by_ip(event.ip_address) .blocked .where(timestamp: 1.hour.ago..Time.current) if recent_blocks.count >= 5 # Log IP reputation issue - no automatic IP blocking without projects Rails.logger.warn "IP with poor reputation detected: #{event.ip_address} (#{recent_blocks.count} blocks in 1 hour)" end end def analyze_user_agent_patterns(event) return unless event.user_agent.present? # Look for common bot/user agent patterns suspicious_patterns = [ /bot/i, /crawler/i, /spider/i, /scanner/i, /python/i, /curl/i, /wget/i, /nmap/i ] if suspicious_patterns.any? { |pattern| event.user_agent.match?(pattern) } # Log suspicious user agent for potential rule generation Rails.logger.info "Suspicious user agent detected: #{event.user_agent}" end end def analyze_path_attacks(event) return unless event.request_path.present? # Look for common attack paths attack_patterns = [ /\.\./, # Directory traversal /admin/i, # Admin panel access /wp-admin/i, # WordPress admin /\.php/i, # PHP files /union.*select/i, # SQL injection /script.*>/i # XSS attempts ] if attack_patterns.any? { |pattern| event.request_path.match?(pattern) } Rails.logger.info "Potential attack path detected: #{event.request_path}" end end def update_analytics_cache # Update cached analytics for faster dashboard loading Rails.cache.delete("global_analytics") end end