Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

/upload 500 PIL.Image.DecompressionBombError #10028

Closed
t3chguy opened this issue May 20, 2021 · 1 comment · Fixed by #10029
Closed

/upload 500 PIL.Image.DecompressionBombError #10028

t3chguy opened this issue May 20, 2021 · 1 comment · Fixed by #10029
Labels
A-Media-Repository Uploading, downloading images and video, thumbnailing T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues.

Comments

@t3chguy
Copy link
Member

t3chguy commented May 20, 2021

Description

When uploading a large image, e.g one from https://visibleearth.nasa.gov/images/73751/july-blue-marble-next-generation-w-topography-and-bathymetry the /upload 500s. The file fits within the size constraint. Max pixel count in config talks only about whether or not it will get thumbnailed - https://github.com/matrix-org/synapse/blob/develop/docs/sample_config.yaml#L986-L988

Steps to reproduce

  • Upload large image
  • Observe 500 instead of image uploaded possibly without functioning thumbnails

Version information

  • Homeserver: matrix.org
2021-05-20 13:21:22,554 - synapse.http.server - 97 - ERROR - POST-593969 - Failed handle request via 'UploadResource': <XForwardedForRequest at 0x7f0e8624fd58 method='POST' uri='/_matrix/media/r0/upload?filename=world.topo.bathy.200407.3x21600x21600.C1.jpg' clientproto='HTTP/1.1' site=8112>
Capture point (most recent call last):
  File "/usr/local/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/synapse/src/synapse/app/media_repository.py", line 23, in <module>
    start(sys.argv[1:])
  File "/home/synapse/src/synapse/app/generic_worker.py", line 478, in start
    _base.start_worker_reactor("synapse-generic-worker", config)
  File "/home/synapse/src/synapse/app/_base.py", line 85, in start_worker_reactor
    run_command=run_command,
  File "/home/synapse/src/synapse/app/_base.py", line 139, in start_reactor
    run()
  File "/home/synapse/src/synapse/app/_base.py", line 123, in run
    run_command()
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/base.py", line 1423, in run
    self.mainLoop()
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/base.py", line 1433, in mainLoop
    reactorBaseSelf.runUntilCurrent()
  File "/home/synapse/src/synapse/metrics/__init__.py", line 565, in f
    ret = func(*args, **kwargs)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/base.py", line 972, in runUntilCurrent
    f(*a, **kw)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/defer.py", line 477, in callback
    self._startRunCallbacks(result)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/defer.py", line 580, in _startRunCallbacks
    self._runCallbacks()
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/defer.py", line 662, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/defer.py", line 1511, in gotResult
    current_context.run(_inlineCallbacks, r, g, status)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/twisted/internet/defer.py", line 1445, in _inlineCallbacks
    result = current_context.run(g.send, result)
  File "/home/synapse/src/synapse/http/server.py", line 184, in wrapped_async_request_handler
    await h(self, request)
Traceback (most recent call last):
  File "/home/synapse/src/synapse/http/server.py", line 258, in _async_render_wrapper
    callback_return = await self._async_render(request)
  File "/home/synapse/src/synapse/http/server.py", line 286, in _async_render
    callback_return = await raw_callback_return
  File "/home/synapse/src/synapse/rest/media/v1/upload_resource.py", line 93, in _async_render_POST
    media_type, upload_name, content, content_length, requester.user
  File "/home/synapse/src/synapse/rest/media/v1/media_repository.py", line 180, in create_content
    await self._generate_thumbnails(None, media_id, media_id, media_type)
  File "/home/synapse/src/synapse/rest/media/v1/media_repository.py", line 682, in _generate_thumbnails
    thumbnailer = Thumbnailer(input_path)
  File "/home/synapse/src/synapse/rest/media/v1/thumbnailer.py", line 45, in __init__
    self.image = Image.open(input_path)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/PIL/Image.py", line 2804, in open
    im = _open_core(fp, filename, prefix)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/PIL/Image.py", line 2791, in _open_core
    _decompression_bomb_check(im.size)
  File "/home/synapse/env-py37/lib/python3.7/site-packages/PIL/Image.py", line 2724, in _decompression_bomb_check
    "could be decompression bomb DOS attack." % (pixels, 2 * MAX_IMAGE_PIXELS)
PIL.Image.DecompressionBombError: Image size (466560000 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack.
@t3chguy
Copy link
Member Author

t3chguy commented May 20, 2021

Oh this is a fun one!!

https://github.com/matrix-org/synapse/blob/develop/synapse/rest/media/v1/media_repository.py#L681-L703

To respect max_image_pixels it has to load the image into PIL to get its dimensions to calculate its resolution, except that can explode in the case of way too many pixels.

This needs a try-except
It'd also be good to set PIL.Image.MAX_IMAGE_PIXELS to max_image_pixels so that PIL bombs out quicker to save it having to load more pixels into RAM than it has to

@MadLittleMods MadLittleMods added A-Media-Repository Uploading, downloading images and video, thumbnailing T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues. labels Jun 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-Media-Repository Uploading, downloading images and video, thumbnailing T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants