diff --git a/wagtail/wagtailimages/urls.py b/wagtail/wagtailimages/urls.py index f36adfe64..2421a7acd 100644 --- a/wagtail/wagtailimages/urls.py +++ b/wagtail/wagtailimages/urls.py @@ -3,5 +3,5 @@ from wagtail.wagtailimages.views import frontend urlpatterns = [ - url(r'^(\d*)/(.*)/$', frontend.serve, name='wagtailimages_serve'), + url(r'^(.*)/(\d*)/(.*)/$', frontend.serve, name='wagtailimages_serve'), ] diff --git a/wagtail/wagtailimages/utils.py b/wagtail/wagtailimages/utils.py index c94bf96db..0f718fb35 100644 --- a/wagtail/wagtailimages/utils.py +++ b/wagtail/wagtailimages/utils.py @@ -1,10 +1,15 @@ import os import re +import base64 +import hmac +import hashlib + from PIL import Image from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ +from django.conf import settings def validate_image_format(f): @@ -68,3 +73,14 @@ def parse_filter_spec(filter_spec): return OPERATION_NAMES[match.group(1)], (width, height) raise InvalidFilterSpecError(filter_spec) + + +def generate_signature(image_id, filter_spec): + # Based on libthumbor hmac generation + # https://github.com/thumbor/libthumbor/blob/b19dc58cf84787e08c8e397ab322e86268bb4345/libthumbor/crypto.py#L50 + url = str(image_id) + '/' + filter_spec + '/' + return base64.urlsafe_b64encode(hmac.new(settings.SECRET_KEY, url, hashlib.sha1).digest()) + + +def verify_signature(signature, image_id, filter_spec): + return signature == generate_signature(image_id, filter_spec) diff --git a/wagtail/wagtailimages/views/frontend.py b/wagtail/wagtailimages/views/frontend.py index 1ae145d7b..80ab989ff 100644 --- a/wagtail/wagtailimages/views/frontend.py +++ b/wagtail/wagtailimages/views/frontend.py @@ -1,14 +1,18 @@ from django.shortcuts import get_object_or_404 from django.http import HttpResponse +from django.core.exceptions import PermissionDenied from wagtail.wagtailimages.models import get_image_model -from wagtail.wagtailimages.utils import InvalidFilterSpecError +from wagtail.wagtailimages.utils import InvalidFilterSpecError, verify_signature from wagtail.wagtailimages import image_processor -def serve(request, image_id, filter_spec): +def serve(request, signature, image_id, filter_spec): image = get_object_or_404(get_image_model(), id=image_id) + if not verify_signature(signature, image_id, filter_spec): + raise PermissionDenied + try: return image_processor.process_image(image.file.file, HttpResponse(content_type='image/jpeg'), filter_spec) except InvalidFilterSpecError: