Images uploaded with wrong extension trigger ActiveStorage::IntegrityError
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 55/100
Piste de recherche
Commencez par ActiveStorage::Service::CloudinaryService#ext_for_file et comparez sa sélection d’extension avec le monkey patch signalé. Reproduisez un Rails Direct Upload en utilisant un JPEG dont le nom se termine par .png, puis suivez l’URL Cloudinary, le checksum du blob et le chemin vers ActiveStorage::IntegrityError. Le travail est terminé lorsque l’image téléversée à l’origine peut être téléchargée et analysée sans différence de checksum ni transformation de format involontaire.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Describe the bug in a sentence or two.
When using Rails Direct Uploads, we can't analyze a file before it reaches Cloudinary. If a user uploads an image with the wrong extension (say a JPEG named image.png), then Cloudinary will return an URL ending with .png, which requests a transformation of the image to PNG, resulting in a checksum that does not match the one stored in the associated ActiveStorage::Blob, which triggers ActiveStorage::IntegrityError.
Issue Type (Can be multiple)
- Build - Cannot install or import the SDK
- Performance - Performance issues
- Behaviour - Functions are not working as expected (such as generate URL)
- Documentation - Inconsistency between the docs and behaviour
- Other (Specify)
Operating System
- Linux
- Windows
- macOS
- All
Environment and Libraries (fill in the version numbers)
- Cloudinary Ruby SDK version - 2.4.4
- Ruby Version - 3.4.10
- Rails Version - 8.1.3
Current workaround
In our codebase, we monkey patched ActiveStorage::Service::CloudinaryService#ext_for_file like this as a workaround:
# The original ext_for_file method takes the extension from the filename and only falls back to the
# content type when the filename carries none. What this patch does is let Rails determine the real
# content type of the file, and if it matches the filename extension return this extension, otherwise
# return an extension that really matches the content_type.
#
# This logic does not apply to "raw" resource types, as these are never transcoded by cloudinary.
def ext_for_file(key, filename = nil, content_type = nil)
attributes = key.is_a?(ActiveStorage::BlobKey) ? key.attributes : {}
content_type = content_type.presence || attributes[:content_type]
return super if content_type_to_resource_type(content_type).eql?('raw')
# { 'identified' => true } in metadata means Rails has analyzed the file and determined its true
# content type. It does that by downloading the file from the provided url, at the moment of
# attaching the blob to the record. Before that, the content type is what the client said it was,
# which can be wrong. Returning nil before identification forces no extension and therefore no
# conversion on the Cloudinary side. That allows Rails to download and analyze the original file
# intead of a converted one.
return nil unless attributes.dig(:metadata, 'identified')
filename = ActiveStorage::Filename.wrap(filename.presence || attributes[:filename])
filename_extension = filename.extension_without_delimiter
content_type_extensions = Marcel::TYPE_EXTS[content_type]
return filename_extension if content_type_extensions.blank?
content_type_extensions.find { it == filename_extension } || content_type_extensions.first
end
- Langage dominant
- Ruby
- Étoiles
- 420
- Forks
- 282
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de cloudinary/cloudinary_gem
-
Difficulté 2/5 1-3 heures Accessibilité débutants 52/100
cloudinary/cloudinary_gem#591 · 3 commentaires ·
-
Difficulté 3/5 1-2 jours Accessibilité débutants 45/100
cloudinary/cloudinary_gem#582 · 1 commentaire ·
-
404's when fetching .eml files (from Action Mailbox)Peut-être à nouveau libre @rnamba-cloudinary l’a pris il y a 400 jours, et aucune pull request n’est ouverte. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 30/100
cloudinary/cloudinary_gem#581 · 1 commentaire ·
-
BlobKey, MirrorService and Sidekiq 8 are incompatiblePeut-être à nouveau libre @const-cloudinary l’a pris il y a 541 jours, et aucune pull request n’est ouverte. Ouverte
cloudinary/cloudinary_gem#573 · 3 commentaires · 1 personne assignée ·
-
ActiveStorage Mirror IssueOuverte
Difficulté 4/5 3-5 jours Accessibilité débutants 30/100
cloudinary/cloudinary_gem#562 · 9 commentaires ·
Toutes les issues de cloudinary/cloudinary_gem
Issues similaires
-
bug
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
yegor256/mailanes#361 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Property accounts have no notes fieldPeut-être pris @arnaurodondev l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
we-promise/sure#5057 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
metacall/core#964 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
area: ci benchmark build developer-experience difficulty: easy dx enhancement github-actions good first issue hacktoberfest help wanted performance quality rank: 8 kyu ruby tech: ruby
Difficulté 1/5 Moins d'une heure Accessibilité débutants 82/100
flisk-sh/flisk-labs#22 ·
-
1.severity: security
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
Les mainteneurs répondent en général sous 1 jour