Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ExcelAnalyzer] add on_hidden_metadata callback #8136

Merged
merged 1 commit into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions gems/excel_analyzer/lib/excel_analyzer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ module ExcelAnalyzer
# @return [Proc] the callable to run for spreadsheet attachments
mattr_accessor :on_spreadsheet_received, default: ->(blob) {}

# A configurable callable that gets executed when an analyzed spreadsheet
# contains signs of hidden data. This can be useful for raising alerts,
# logging incidents, or taking other custom actions.
#
# @example Set a custom callable to handle hidden metadata detection
# ExcelAnalyzer.on_hidden_metadata = ->(blob, metadata) { alert(blob) }
#
# @!attribute [rw] on_hidden_metadata
# @return [Proc] the callable to run when hidden metadata is detected in a
# spreadsheet
mattr_accessor :on_hidden_metadata, default: ->(blob, metadata) {}

# Provides the list of content types that the ExcelAnalyzer will attempt to
# analyze in search of hidden data. It currently includes content types for
# .xls and .xlsx files.
Expand Down
14 changes: 13 additions & 1 deletion gems/excel_analyzer/lib/excel_analyzer/xlsx_analyzer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ def self.accept?(blob)
end

def metadata
{ excel: excel_metadata }
data = excel_metadata

if suspected_problem?(data)
# rubocop:disable Style/RescueModifier
ExcelAnalyzer.on_hidden_metadata.call(blob, data) rescue nil
# rubocop:enable Style/RescueModifier
end

{ excel: data }
end

private
Expand All @@ -29,5 +37,9 @@ def excel_metadata
rescue StandardError => ex
{ error: ex.message }
end

def suspected_problem?(data)
data.any? { |k, v| k != :error && k != :named_ranges && v > 1 }
end
end
end
22 changes: 22 additions & 0 deletions gems/excel_analyzer/spec/excel_analyzer/xlsx_analyzer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
end

describe "#metadata" do
around do |example|
original_callback = ExcelAnalyzer.on_hidden_metadata
ExcelAnalyzer.on_hidden_metadata = ->(blob) {}
example.call
ExcelAnalyzer.on_hidden_metadata = original_callback
end

let(:metadata) { ExcelAnalyzer::XlsxAnalyzer.new(blob).metadata }

context "when the blob is an Excel file with hidden data" do
Expand Down Expand Up @@ -70,6 +77,11 @@
it "detects pivot cache" do
expect(metadata[:excel][:pivot_cache]).to eq 1
end

it "does not call on_hidden_metadata callback" do
expect(ExcelAnalyzer.on_hidden_metadata).to receive(:call)
metadata
end
end

context "when the blob is an Excel file without hidden data" do
Expand All @@ -89,6 +101,11 @@
pivot_cache: 0
)
end

it "does not call on_hidden_metadata callback" do
expect(ExcelAnalyzer.on_hidden_metadata).to_not receive(:call)
metadata
end
end

context "when the blob is not an Excel file" do
Expand All @@ -102,6 +119,11 @@
error: "Zip end of central directory signature not found"
)
end

it "does not call on_hidden_metadata callback" do
expect(ExcelAnalyzer.on_hidden_metadata).to_not receive(:call)
metadata
end
end
end
end