Skip to content

Commit

Permalink
[ExcelAnalyzer] add on_hidden_metadata callback
Browse files Browse the repository at this point in the history
Allow a configurable block to be called if spreadsheets are received
which contain suspect hidden data.
  • Loading branch information
gbp committed Feb 23, 2024
1 parent 08aa218 commit b537ab4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
12 changes: 12 additions & 0 deletions gems/excel_analyzer/lib/excel_analyzer.rb
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
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
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

0 comments on commit b537ab4

Please sign in to comment.