Class: ActiveStorageValidations::ProcessableFileValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Includes:
ASVActiveStorageable, ASVAnalyzable, ASVAttachable, ASVErrorable, ASVSymbolizable
Defined in:
lib/active_storage_validations/processable_file_validator.rb

Overview

:nodoc

Constant Summary collapse

ERROR_TYPES =
%i[
  file_not_processable
].freeze
METADATA_KEYS =
%i[].freeze
VIPS_UNTRUSTED_CONTENT_TYPES =

Content types whose libvips loaders are marked untrusted / unfuzzed (VIPS_OPERATION_UNTRUSTED). After Rails calls Vips.block_untrusted(true), analysis of these types returns no width/height (empty metadata here), which is not the same as a corrupt / unprocessable file.

Matches the formats called out in the Active Storage security release changelogs (7.2.3.2 / 8.0.5.1 / 8.1.3.1): https://github.com/rails/rails/blob/v8.1.3.1/activestorage/CHANGELOG.md https://github.com/rails/rails/security/advisories/GHSA-xr9x-r78c-5hrm

%w[
  image/bmp
  image/vnd.microsoft.icon
  image/vnd.adobe.photoshop
  image/svg+xml
  image/jxl
  image/jp2
  image/x-portable-anymap
  image/x-portable-bitmap
  image/x-portable-graymap
  image/x-portable-pixmap
].freeze

Constants included from ASVAnalyzable

ASVAnalyzable::DEFAULT_IMAGE_PROCESSOR

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ASVErrorable

#add_error, #initialize_error_options

Class Method Details

.reset_vips_untrusted_operations_blocked_cache!Object



76
77
78
# File 'lib/active_storage_validations/processable_file_validator.rb', line 76

def reset_vips_untrusted_operations_blocked_cache!
  remove_instance_variable(:@vips_untrusted_operations_blocked) if defined?(@vips_untrusted_operations_blocked)
end

.vips_untrusted_operations_blocked?Boolean

Detect whether libvips is currently blocking untrusted operations. There is no public getter for Vips.block_untrusted, so we probe whether an untrusted loader (svgload) is available via vips_foreign_find_load.

Returns:

  • (Boolean)


70
71
72
73
74
# File 'lib/active_storage_validations/processable_file_validator.rb', line 70

def vips_untrusted_operations_blocked?
  return @vips_untrusted_operations_blocked if defined?(@vips_untrusted_operations_blocked)

  @vips_untrusted_operations_blocked = detect_vips_untrusted_operations_blocked?
end

Instance Method Details

#validate_each(record, attribute, _value) ⇒ Object



44
45
46
47
48
# File 'lib/active_storage_validations/processable_file_validator.rb', line 44

def validate_each(record, attribute, _value)
  return if no_attachments?(record, attribute)

  (record, attribute, METADATA_KEYS)
end