From 9a7318a9dbf01b4b9d6da8d691f590a886bf576c Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Wed, 13 Aug 2025 07:56:58 +0530 Subject: [PATCH] fix: cw-5411 handle unrepresentable image attachments (#12178) # Pull Request Template ## Description Fixes https://linear.app/chatwoot/issue/CW-5411/actionviewtemplateerror-activestorageunrepresentableerror ### Problem API endpoints return 500 errors when conversations contain image attachments that can't be processed by ActiveStorage (e.g., files with non-ASCII filenames, corrupted images, or malicious XSS filenames). Root Cause: Commit 6cab74139 removed the representable? safety check from thumb_url, causing `ActiveStorage::UnrepresentableError` to bubble up and crash the API when it encountered a malformed image file. Fix: Rescue `thumb_url` method to catch UnrepresentableError and return an empty string while logging problematic names for future debugging. This ensures the messages/attachments api does not break due to a single corrupted image file. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Added specs ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules --- app/models/attachment.rb | 7 ++++++- spec/models/attachment_spec.rb | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 8c5750148..42ca79d6c 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -62,7 +62,12 @@ class Attachment < ApplicationRecord def thumb_url return '' unless file.attached? && image? - url_for(file.representation(resize_to_fill: [250, nil])) + begin + url_for(file.representation(resize_to_fill: [250, nil])) + rescue ActiveStorage::UnrepresentableError => e + Rails.logger.warn "Unrepresentable image attachment: #{id} (#{file.filename}) - #{e.message}" + '' + end end def with_attached_file? diff --git a/spec/models/attachment_spec.rb b/spec/models/attachment_spec.rb index 0b03a56ad..cc00eab5d 100644 --- a/spec/models/attachment_spec.rb +++ b/spec/models/attachment_spec.rb @@ -82,6 +82,16 @@ RSpec.describe Attachment do expect(attachment.thumb_url).to be_present end + + it 'handles unrepresentable images gracefully' do + attachment = message.attachments.create!(account_id: message.account_id, file_type: :image) + attachment.file.attach(io: StringIO.new('fake image'), filename: 'test.jpg', content_type: 'image/jpeg') + + allow(attachment.file).to receive(:representation).and_raise(ActiveStorage::UnrepresentableError.new('Cannot represent')) + + expect(Rails.logger).to receive(:warn).with(/Unrepresentable image attachment: #{attachment.id}/) + expect(attachment.thumb_url).to eq('') + end end describe 'meta data handling' do