From b7733da08d1d5ffc1d5e5c0530146525a4d5cfc5 Mon Sep 17 00:00:00 2001 From: Gil Desmarais Date: Thu, 22 Oct 2026 10:59:43 +0200 Subject: [PATCH] fix(obs): copy security_event onto event_name --- app/web/security/security_logger.rb | 5 ++++- spec/html2rss/web/log_sanitizer_spec.rb | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/web/security/security_logger.rb b/app/web/security/security_logger.rb index 63b8b61e1..cbd4d5336 100644 --- a/app/web/security/security_logger.rb +++ b/app/web/security/security_logger.rb @@ -73,7 +73,10 @@ def log_blocked_request(ip, reason, endpoint) # @param severity [Symbol] # @return [void] def log_event(event_type, data, severity: :warn) - LogEvent.emit(level: severity, payload: { security_event: event_type, details: data }) + LogEvent.emit( + level: severity, + payload: { security_event: event_type, event_name: event_type, details: data } + ) end end end diff --git a/spec/html2rss/web/log_sanitizer_spec.rb b/spec/html2rss/web/log_sanitizer_spec.rb index 46bd40637..47d310ffc 100644 --- a/spec/html2rss/web/log_sanitizer_spec.rb +++ b/spec/html2rss/web/log_sanitizer_spec.rb @@ -85,7 +85,9 @@ Html2rss::Web::SecurityLogger.log_token_usage('very-secret-token', 'https://news.ycombinator.com', true) payload = JSON.parse(io.string.lines.last, symbolize_names: true) - expect(payload.slice(:path, :details)).to eq( + expect(payload.slice(:security_event, :event_name, :path, :details)).to eq( + security_event: 'token_usage', + event_name: 'token_usage', path: '/api/v1/feeds/[REDACTED]', details: { url: expected_news_url, @@ -95,6 +97,16 @@ ) end + it 'copies security_event onto event_name for rate limit exceeded' do + Html2rss::Web::SecurityLogger.log_rate_limit_exceeded('203.0.113.10', '/api/v1/feeds', 60) + payload = JSON.parse(io.string.lines.last, symbolize_names: true) + + expect(payload.slice(:security_event, :event_name)).to eq( + security_event: 'rate_limit_exceeded', + event_name: 'rate_limit_exceeded' + ) + end + it 'sanitizes security logger fallback output when structured logging fails' do failing_logger = instance_double(Logger) allow(failing_logger).to receive(:info).and_raise(JSON::GeneratorError, 'boom') @@ -205,7 +217,7 @@ def sanitized_fallback_url # @return [String] def expected_fallback_warning_line - 'payload={security_event: "token_usage", details: {success: true, ' \ + 'payload={security_event: "token_usage", event_name: "token_usage", details: {success: true, ' \ "url: #{sanitized_fallback_url.inspect}, token_hash: \"01cadf39\"}}" end end