Sometimes a client makes a blog post, and puts a photo in the middle. All good so far, until you realise the client has dragged an image from their brand new camera expecting a 10 Megapixel image to work.
This is usually when people start talking about upload max file size limits, but this is not a file size issue. The photograph uploaded fine, it was the resizing that crippled the insertion!
So you do some research and decide to bump up the memory allocated to PHP, crisis avert.
6 months later they phone up. Turns out they’ve bought a new camera and they’re now uploading 14 Megapixel images.
The problem is that PNG/JPEG/GIF/etc are all compressed image formats. That photograph may be 10MB on your file system, but it could be hundreds of megabytes in RAM once decompressed. When WordPress recieves an image, it needs to decompress it and generate additional images for each image size you’ve registered, thumbnail, medium, full, etc.
Rather than fight the arms race of ever increasing memory requirements, or the arduous task of reteaching clients that they need to resize images prior to upload, there is an alternative. You can hook into the upload process and refuse to accept files depending on their image dimensions.
Security & Decompression Bombs
There’s another important reason for doing this. Remember earlier when I mentioned compression and the size of images in memory? There’s a class of exploits known as decompression bombs that take advantage of this.
For example, PNG compression excels at repeating, uniform data. So, a 30,000×30,000 pixel image with nothing but white pixels, can be compressed down to an incredibly tiny size, yet when expanded in memory consumes a huge amount of RAM. Other decompression bombs include GZIP’d webpages and files.
The primary goal of decompression bombs is resource deprivation. One can take down a machine running with 4GB by loading a webpage with numerous decompression bombs referenced as images or as JS/CSS includes using GZIP bombs.
So if somebody uploaded a 2kb PNG image that expanded to a multi GB RAW image in system memory when decompressed, no max upload limit is going to be of use. a rogue user could take down a server given image upload access.
Prevention
I’ve written a small plugin to prevent these uploads. It will limit the image to a maximum of 3.2 Megapixels, and refuse larger images
View the code on Gist.
Lovely! RT @Tarendai: New Blogpost: Fixing Clients Who Upload Huge Photos & Decompression Bombs http://t.co/OMyaia37kE #wordpress
RT @DeFries Lovely! RT @Tarendai: New Blogpost: Fixing Clients Who Upload Huge Photos & Decompression Bombs http://t.co/6ivWU692dl #w…
Fixing Clients Who Upload Huge Photos & Decompression Bombs http://t.co/YDYAGxxYfc #wordpress /by @Tarendai /via @defries
I’ve combined both our solutions that came out of the WP.SE answers and host them as a Gist: https://gist.github.com/franz-josef-kaiser/5037559
Better still: you can resize the image client-side with canvas, and only upload the smaller image, completely transparently to the user. (You’ll still need the server-side checks, of course.)
Nice! Needs building first, but that should speed up uploads too
Thank you Tom!
Your idea turned into an MU plugin called “Image upload control”
https://github.com/szepeviktor/wordpress-plugin-construction/tree/master/mu-image-upload-control