Description
In v13.0.0, the serialize_storage() method was changed to resolve storage aliases by iterating through storages.backends and matching on the BACKEND class name. This approach has a bug: when multiple storages are configured with the same BACKEND class (but different options), the method returns the first matching alias rather than the correct one.
This causes incorrect cache keys to be generated, resulting in thumbnail collisions when files with the same name exist across different storages.
Explanation
def serialize_storage(self):
# ...
backend = f"{cls.__module__}.{cls.__name__}"
# Try our best to find and serialize the storage alias instead of the backend class.
for alias, params in storages.backends.items():
if params.get("BACKEND") == backend:
return alias
return backend
The problem is that params.get("BACKEND") == backend only compares the class name, not the actual storage instance or its configuration.
Reproduction
The MRE below is a bit of a toy example. In a production environment, there are various other mitigations that might stop this (i.e., renaming files to unique IDs on upload, etc).
Regardless, there is still a bug here - sorl-thumbnail is attributing the wrong storage to source image files, and generating cache keys for thumbnails based on it.
Minimal reproducible example: https://github.com/SupImDos/sorl-thumbnail-unique-storage-mre
When the same filename exists in both storages with different images, the wrong thumbnail is shown:

Description
In v13.0.0, the
serialize_storage()method was changed to resolve storage aliases by iterating throughstorages.backendsand matching on theBACKENDclass name. This approach has a bug: when multiple storages are configured with the sameBACKENDclass (but different options), the method returns the first matching alias rather than the correct one.This causes incorrect cache keys to be generated, resulting in thumbnail collisions when files with the same name exist across different storages.
Explanation
The problem is that
params.get("BACKEND") == backendonly compares the class name, not the actual storage instance or its configuration.Reproduction
The MRE below is a bit of a toy example. In a production environment, there are various other mitigations that might stop this (i.e., renaming files to unique IDs on upload, etc).
Regardless, there is still a bug here -
sorl-thumbnailis attributing the wrong storage to source image files, and generating cache keys for thumbnails based on it.Minimal reproducible example: https://github.com/SupImDos/sorl-thumbnail-unique-storage-mre
When the same filename exists in both storages with different images, the wrong thumbnail is shown: