From 45bb56ad1d809bead00379e68144e91bb471da06 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Mon, 3 Aug 2026 03:13:48 +0200 Subject: Run ImageMagick under a policy that travels with the project --- app/models/concerns/file_attachment.rb | 16 +++++++++--- config/imagemagick/policy.xml | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 config/imagemagick/policy.xml diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index 5e0803fd..fd0cabed 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb @@ -29,6 +29,14 @@ module FileAttachment large: { args: ["-resize", "1600x1600>"] } }.freeze + # Prepended to ImageMagick's configuration search path on every + # invocation, so config/imagemagick/policy.xml is read before the + # installed one. Per-invocation rather than in the environment, so it + # cannot leak into anything else on the host. + MAGICK_ENV = { + "MAGICK_CONFIGURE_PATH" => Rails.root.join("config", "imagemagick").to_s + }.freeze + IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze VECTOR_CONTENT_TYPES = %w[image/svg+xml].freeze RASTERIZED_CONTENT_TYPES = %w[application/pdf].freeze @@ -152,7 +160,7 @@ module FileAttachment STYLES.each do |style, options| dest_path = file_path(style) FileUtils.mkdir_p(File.dirname(dest_path)) - system("magick", original_path, *extra_args, *options[:args], dest_path) + system(MAGICK_ENV, "magick", original_path, *extra_args, *options[:args], dest_path) end end @@ -173,13 +181,13 @@ module FileAttachment FileUtils.mkdir_p(File.dirname(dest_path)) if og_full_bleed?(original_path) - system("magick", "#{original_path}[0]", + system(MAGICK_ENV, "magick", "#{original_path}[0]", "-resize", "#{OG_WIDTH}x#{OG_HEIGHT}^", "-gravity", "center", "-extent", "#{OG_WIDTH}x#{OG_HEIGHT}", "-background", OG_GROUND, "-alpha", "remove", "-alpha", "off", *og_output_args, dest_path) else - system(*og_template_command(dest_path)) + system(MAGICK_ENV, *og_template_command(dest_path)) end end @@ -206,7 +214,7 @@ module FileAttachment end def source_dimensions(path) - out, status = Open3.capture2("magick", "identify", "-format", "%w %h", "#{path}[0]") + out, status = Open3.capture2(MAGICK_ENV, "magick", "identify", "-format", "%w %h", "#{path}[0]") return nil unless status.success? width, height = out.split.map(&:to_i) diff --git a/config/imagemagick/policy.xml b/config/imagemagick/policy.xml new file mode 100644 index 00000000..6106aa0b --- /dev/null +++ b/config/imagemagick/policy.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.3