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!509
merge-requests/552/head
Eliot Berriot 2019-01-02 12:45:04 +01:00
commit 55c4a05b31
5 zmienionych plików z 54 dodań i 2 usunięć

Wyświetl plik

@ -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
)

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -0,0 +1 @@
Strip EXIF metadata from uploaded avatars to avoid leaking private data (#374)