diff --git a/src/pretix/helpers/apps.py b/src/pretix/helpers/apps.py index a2ef2d7d9..847fccb6d 100644 --- a/src/pretix/helpers/apps.py +++ b/src/pretix/helpers/apps.py @@ -30,7 +30,7 @@ class PretixHelpersConfig(AppConfig): from .monkeypatching import monkeypatch_all_at_ready monkeypatch_all_at_ready() - # Ensure reportlab does not make any calls to the internet + # Ensure reportlab does not make any calls to the internet or the local disk from reportlab import rl_config rl_config.trustedHosts = [] rl_config.trustedSchemes = ['data'] diff --git a/src/pretix/helpers/monkeypatching.py b/src/pretix/helpers/monkeypatching.py index 8d824612c..909d0400a 100644 --- a/src/pretix/helpers/monkeypatching.py +++ b/src/pretix/helpers/monkeypatching.py @@ -24,8 +24,11 @@ from datetime import datetime from http import cookies from PIL import Image +from django.core.exceptions import SuspiciousFileOperation from requests.adapters import HTTPAdapter +from pretix.helpers.reportlab import ThumbnailingImageReader + def monkeypatch_vobject_performance(): """ @@ -95,8 +98,26 @@ def monkeypatch_cookie_morsel(): cookies.Morsel._reserved.setdefault("partitioned", "Partitioned") +def monkeypatch_reportlab_imagereader(): + from reportlab.lib import utils + old_init = utils.ImageReader.__init__ + + def new_init(self, fileName, ident=None): # noqa + if not isinstance(fileName, Image.Image) and not hasattr(fileName, 'read') and not hasattr(fileName, 'str'): + if not isinstance(self, ThumbnailingImageReader): + # ThumbnailingImageReader is only used by us explicitly and not by using in html, so it is safe + raise SuspiciousFileOperation("reportlab should not be reading images from disk") + + return types.MethodType(old_init, self)( + fileName, ident + ) + + utils.ImageReader.__init__ = new_init + + def monkeypatch_all_at_ready(): monkeypatch_vobject_performance() monkeypatch_pillow_safer() monkeypatch_requests_timeout() monkeypatch_cookie_morsel() + monkeypatch_reportlab_imagereader() diff --git a/src/tests/helpers/test_reportlab.py b/src/tests/helpers/test_reportlab.py index dcd8f0f5a..354e2cbd1 100644 --- a/src/tests/helpers/test_reportlab.py +++ b/src/tests/helpers/test_reportlab.py @@ -20,6 +20,7 @@ # . # import pytest +from django.core.exceptions import SuspiciousFileOperation from reportlab.platypus import Paragraph @@ -29,24 +30,21 @@ def test_http_access_disabled(monkeypatch): monkeypatch.setattr('socket.socket', guard) - with pytest.raises(OSError, match="Cannot open resource"): + with pytest.raises(SuspiciousFileOperation, match="should not be reading images from disk"): Paragraph( '', ) def test_file_access_disabled_scheme(monkeypatch): - with pytest.raises(OSError, match="Cannot open resource"): + with pytest.raises(SuspiciousFileOperation, match="should not be reading images from disk"): Paragraph( '', ) -@pytest.mark.xfail def test_file_access_disabled_direct(monkeypatch): - # Unfortunately this is not prevented by the reprotlab config, but the risk is low since only valid images - # can be used. - with pytest.raises(OSError, match="Cannot open resource"): + with pytest.raises(SuspiciousFileOperation, match="should not be reading images from disk"): Paragraph( '', )