kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
Merge branch '374-strip-exif' into 'develop'
Fix #374: Strip EXIF metadata from uploaded avatars to avoid leaking private data Closes #374 See merge request funkwhale/funkwhale!509merge-requests/552/head
commit
55c4a05b31
|
@ -1,8 +1,12 @@
|
|||
import collections
|
||||
import io
|
||||
import PIL
|
||||
import os
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -190,3 +194,25 @@ def track_fields_for_update(*fields):
|
|||
return serializer_class
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class StripExifImageField(serializers.ImageField):
|
||||
def to_internal_value(self, data):
|
||||
file_obj = super().to_internal_value(data)
|
||||
|
||||
image = PIL.Image.open(file_obj)
|
||||
data = list(image.getdata())
|
||||
image_without_exif = PIL.Image.new(image.mode, image.size)
|
||||
image_without_exif.putdata(data)
|
||||
|
||||
with io.BytesIO() as output:
|
||||
image_without_exif.save(
|
||||
output,
|
||||
format=PIL.Image.EXTENSION[os.path.splitext(file_obj.name)[-1]],
|
||||
quality=100,
|
||||
)
|
||||
content = output.getvalue()
|
||||
|
||||
return SimpleUploadedFile(
|
||||
file_obj.name, content, content_type=file_obj.content_type
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ from rest_framework import serializers
|
|||
from versatileimagefield.serializers import VersatileImageFieldSerializer
|
||||
|
||||
from funkwhale_api.activity import serializers as activity_serializers
|
||||
|
||||
from funkwhale_api.common import serializers as common_serializers
|
||||
from . import models
|
||||
|
||||
|
||||
|
@ -66,7 +66,13 @@ class UserActivitySerializer(activity_serializers.ModelSerializer):
|
|||
return "Person"
|
||||
|
||||
|
||||
avatar_field = VersatileImageFieldSerializer(allow_null=True, sizes="square")
|
||||
class AvatarField(
|
||||
common_serializers.StripExifImageField, VersatileImageFieldSerializer
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
avatar_field = AvatarField(allow_null=True, sizes="square")
|
||||
|
||||
|
||||
class UserBasicSerializer(serializers.ModelSerializer):
|
||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 4.2 KiB |
|
@ -1,3 +1,8 @@
|
|||
import os
|
||||
import PIL
|
||||
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
|
||||
import django_filters
|
||||
|
||||
from funkwhale_api.common import serializers
|
||||
|
@ -163,3 +168,17 @@ def test_track_fields_for_update(mocker):
|
|||
{"field1": "value1", "field2": "value2"},
|
||||
{"field1": "newvalue1", "field2": "newvalue2"},
|
||||
)
|
||||
|
||||
|
||||
def test_strip_exif_field():
|
||||
source_path = os.path.join(os.path.dirname(__file__), "exif.jpg")
|
||||
source = PIL.Image.open(source_path)
|
||||
|
||||
assert bool(source._getexif())
|
||||
|
||||
with open(source_path, "rb") as f:
|
||||
uploaded = SimpleUploadedFile("source.jpg", f.read(), content_type="image/jpeg")
|
||||
field = serializers.StripExifImageField()
|
||||
|
||||
cleaned = PIL.Image.open(field.to_internal_value(uploaded))
|
||||
assert cleaned._getexif() is None
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Strip EXIF metadata from uploaded avatars to avoid leaking private data (#374)
|
Ładowanie…
Reference in New Issue