ActionText Editor Previews uploaded pre 7.1.3.4 are broken in 7.1.3.4 after a resave
Steps to reproduce
1. Upload an image to an ActionText editor in 7.1.3.4
2. Upgrade to 7.1.3.4
3. resave the model containing the image
4. the image preview in the editor will be broken, but the rendering of the HTML will still contain the image
5. In some cases, trying to modify the broken image will result in the blob getting deleted, or the attachment changing to a RemoteImage
6.When you roll back to 7.1.3.3, the image previews are still broken, so it seems like something in 7.1.3.4 is saving invalid state to the attachment record, preventing it from being successfully rendered by the previous version of the code, resulting in invalid state that can not be recovered.
There does seem to be some work to begin to address the issue here: https://github.com/rails/rails/commit/d6316963ef49d9509a64adc1cb96630a3326b03c
However, applying this patch does not seem to fix data which was created in the interim. I'd love any tips to figure out how to reverse exactly what happened.
Expected behavior
The images previews work across versions.
Actual behavior
The image previews for the editor are broken, and rolling back does not restore the previews.
System configuration
Rails version: 7.1.3.4 Ruby version: 3.2 (tested)
Were you able to see the difference of the content saved to the database in each version?
I'm seeing the same thing after upgrading to 7.1.3.4. As far as I can tell the img tags are being striped out of the rendered content despited the tag being included in the ActionText::ContentHelper.sanitizer.class.allowed_tags. I've only tried to debug this a bit, but the issue appears to be with this change: https://github.com/rails/rails/compare/v7.1.3.3...v7.1.3.4#diff-2845a2dd736db0371741dbae62c17e7fd997c7df8e66596020cff068f456854aR97
That change is the security fix, it should not remove the img tags, but it should remove attributes of the tags that can be used to execute JavaScript.
This test here show the img tag stays there https://github.com/rails/rails/compare/v7.1.3.3...v7.1.3.4#diff-ed3b3d0b222a44b26a29f21855ab7e60b6418d4917a4a312fb43e50b0572730aR83
Thanks for the quick reply.
The closest I got to the database changes i could find in that "working" previews seem to NOT have a blank "content" key in full_attributes.
Broken Preview Attachment
{"sgid"=>
"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJanBuYVdRNkx5OWlZV05yWlhKcmFYUXZRV04wYVhabFUzUnZjbUZuWlRvNlFteHZZaTh4TkRrM05qUV9aWGh3YVhKbGMxOXBiZ1k2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoiYXR0YWNoYWJsZSJ9fQ==--79c8acad3bccbbccf94f76b3adb7ac93f9be339b",
"content_type"=>"image/png",
"url"=>
"http://www.backerkit.test/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBd1JKQWc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--0e9dd2a28e88239c490d2dcd558c2ab73ce0e276/max%20edit.png",
"filename"=>"max edit.png",
"filesize"=>564421,
"width"=>"6330",
"height"=>"2521",
"previewable"=>true,
"presentation"=>"gallery",
"caption"=>"uploaded on .3",
"content"=>""}
full_attributes created on a fresh, native 7.1.3.4 attachment
{"sgid"=>
"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJanBuYVdRNkx5OWlZV05yWlhKcmFYUXZRV04wYVhabFUzUnZjbUZuWlRvNlFteHZZaTh4TkRrM05qWV9aWGh3YVhKbGMxOXBiZ1k2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoiYXR0YWNoYWJsZSJ9fQ==--f5cfc60a65c7e05886ba5a3bc0e1800901b825f4",
"content_type"=>"image/png",
"url"=>
"http://www.backerkit.test/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBd1pKQWc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--7d9ab5dbe5f4c5026a324dc33a3dbb54b13c9960/max%20edit.png",
"filename"=>"max edit.png",
"filesize"=>564421,
"width"=>"6330",
"height"=>"2521",
"previewable"=>true,
"presentation"=>"gallery"}
Unfortunately, I couldn't find where the list of these keys would be stored the ActionText object hierarchy in the database exactly.
I think maybe there is a related issue that the content being present is somehow excaping the wrong thing, or sanitizing with a different set of sanitizers, hence the img getting stripped out.
We experience the same issue and can confirm it was introduced in https://github.com/rails/rails/commit/1ac6d40d36a07b48a67bc7f8627fd1f92bffcb14. Probably https://github.com/rails/rails/pull/52093 provides a fix?
You could try explicitly unsetting the content attribute:
if node.key? "content"
node["content"] = sanitize_content_attachment(node["content"])
end
# Add this line to unset it:
node.delete("content") if node["content"].blank?
https://github.com/rails/rails/blob/52c21f90669ce59adf7deef85a44b6b1a46928fa/actiontext/lib/action_text/content.rb#L100-L102
I'm hitting this issue, too
Here's what I see between a broken and working attachment:
irb(main):037> working_post.body.body.attachments.first.full_attributes
=>
{"sgid"=>
"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJalJuYVdRNkx5OWlhMngwTDBGamRHbDJaVk4wYjNKaFoyVTZPa0pzYjJJdk1UUTVPRFFfWlhod2FYSmxjMTlwYmdZNkJrVlUiLCJleHAiOm51bGwsInB1ciI6ImF0dGFjaGFibGUifX0=--d57d592036b4c7c8ee6252618872855347ee62a0",
"content_type"=>"image/png",
"url"=>
"WORKING URL",
"filename"=>"Screenshot 2024-06-17 at 13.46.11.png",
"filesize"=>378036,
"width"=>2488,
"height"=>1832,
"previewable"=>true,
"presentation"=>"gallery"}
irb(main):038> broken_post.body.body.attachments.first.full_attributes
=>
{"sgid"=>
"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJalJuYVdRNkx5OWlhMngwTDBGamRHbDJaVk4wYjNKaFoyVTZPa0pzYjJJdk1UUTROVGtfWlhod2FYSmxjMTlwYmdZNkJrVlUiLCJleHAiOm51bGwsInB1ciI6ImF0dGFjaGFibGUifX0=--566de2b594249c1b729b6af0ae745768042c8924",
"content_type"=>"image/png",
"url"=>
"URL THAT 404s",
"filename"=>"Screenshot 2024-06-10 at 15.43.05.png",
"filesize"=>"182611",
"width"=>"1738",
"height"=>"738",
"presentation"=>"gallery",
"content"=>""}
The blank content is the obvious problem.
It's suspicious to me that the filesize goes from an int to a string, too
Edit: one other clue is that embeds aren't being detected
irb(main):004> broken_post.body.embeds.size
=> 0
irb(main):005> working_post.body.embeds.size
=> 4
I faced the same problem (previews uploaded pre-7.1.3.4 are broken in 7.1.3.4), and what I ended up doing is:
- Downgraded Rails to 7.1.3.3;
- Manually removed all empty content tags from our RichText models with the following script:
ActionText::RichText.where("body ilike '%content=\"\"%'").find_each do |rich_text|
old_body = rich_text.body.to_html
new_body = old_body.gsub('content=""', "")
rich_text.update_column(:body, new_body)
end
Can you confirm this was fixed in 7.1.4?
re ...or the attachment changing to a RemoteImage. Most of our customers attachments have been converted to remote images, while we still have the image stored in our S3. This results in the image not showing, even though we have reverted back to 7.1.3.3
How can we convert the RemoteImages back to Blobs?
We are able to find the old storage key through the active_storage_attachments table.
ActiveStorage::Attachment.find(x).blob
and also the attachments with
ActiveStorage::Attachment.find(x).record.body.attachables
The filename matches the end of the remote image url and the blob. So we are able to cross reference them to each other. The only piece we are missing is converting/overwriting the remote image to the blob we already have stored.
This issue has been automatically closed because there has been no follow-up response from the original author. We currently don't have enough information in order to take action. Please reach out if you have any additional information that will help us move this issue forward.