#64798 closed enhancement (fixed)
REST API: Add dimension validation to sideload endpoint
| Reported by: | adamsilverstein | Owned by: | adamsilverstein |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.1 |
| Component: | REST API | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests commit |
| Cc: | Focuses: |
Description (last modified by )
Summary
Backport for https://github.com/WordPress/wordpress-develop/pull/11100
Add image dimension validation to the wp/v2/media/<id>/sideload REST API endpoint to prevent uploading images with dimensions that don't match the target image size constraints.
Description
The REST API sideload endpoint (wp/v2/media/<id>/sideload) currently accepts uploaded images without validating that their dimensions are appropriate for the specified image_size. This means a client could sideload a 640x480 image as a thumbnail (which is registered as 150x150), producing incorrect metadata and potentially broken layouts.
This ticket adds a validate_image_dimensions() method to WP_REST_Attachments_Controller that validates uploaded image dimensions before processing, with size-specific rules:
Validation rules
originalsize: Uploaded dimensions must match the original attachment dimensions exactly.fullandscaledsizes: Only requires positive dimensions (no upper bound constraint).- Regular registered sizes (e.g.
thumbnail,medium,large): Dimensions must not exceed the registered size maximums, with a 1px tolerance for rounding differences. - Unknown sizes: Returns an error for unregistered image size names.
Implementation details
- Adds private method
validate_image_dimensions( int $width, int $height, string $image_size, int $attachment_id )toWP_REST_Attachments_Controller. - Moves the
wp_getimagesize()call earlier insideload_item()so dimensions are available for validation before metadata handling. - On validation failure, cleans up the uploaded file with
wp_delete_file()before returning the error. - Uses
wp_get_registered_image_subsizes()to look up size constraints for registered sizes.
Error codes
rest_upload_invalid_dimensions— Image has zero or negative dimensions.rest_upload_dimension_mismatch— Dimensions don't match expected constraints for the target size.rest_upload_unknown_size— The specifiedimage_sizeis not registered.
All errors return HTTP 400 status.
Change History (12)
This ticket was mentioned in PR #11100 on WordPress/wordpress-develop by @adamsilverstein.
5 months ago
#2
- Keywords has-patch added
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
5 months ago
@adamsilverstein commented on PR #11100:
3 months ago
#6
Pushed c57a9752cc addressing @apermo's two suggestions (in_array() + dimension_exceeds_max() helper).
Re-merging trunk: skipped intentionally for now. Trunk currently has the entire client-side media feature removed (commit c863860ccf, "Media: Remove client-side media processing feature for now."), including the sideload endpoint this PR validates against. The feature is being re-introduced in #11324, which is still open. Merging trunk here today would just delete the endpoint this PR builds on, so it's better to wait for #11324 to land and then rebase. CI on this branch will look red until then for the same reason.
@westonruter commented on PR #11100:
3 months ago
#8
I fixed some PHPStan errors in 5634d1d. The remaining issues are addressed by the types added in https://github.com/WordPress/wordpress-develop/pull/12003.
@westonruter commented on PR #11100:
3 months ago
#9
The changes look good, but there aren't tests added. Are these still coming?
@adamsilverstein commented on PR #11100:
6 weeks ago
#10
The changes look good, but there aren't tests added. Are these still coming?
Added.
This ticket was mentioned in PR #12550 on WordPress/wordpress-develop by @adamsilverstein.
4 weeks ago
#12
Backport of https://github.com/WordPress/gutenberg/pull/80295 (part of https://github.com/WordPress/gutenberg/issues/77582).
## Problem
In the client-side media upload flow, the client uploads the original file unmodified, applies the EXIF rotation itself, and sideloads the rotated file with image_size=original. For quarter-turn orientations (EXIF 5-8) the rotated file's width and height are swapped relative to the stored metadata, so validate_image_dimensions() rejected the sideload with a 400 (rest_upload_dimension_mismatch) and the upload failed.
The original sideload also stored the rotated file as original_image while the un-rotated upload stayed the attachment's main file, which is backwards relative to what core does when it rotates on upload.
## Solution
- Treat an
image_size=originalsideload like ascaledsideload: the supplied (rotated) file replaces the attachment's main file, and the untouched upload is kept asoriginal_image. This mirrors the swap_wp_image_meta_replace_original()performs inwp_create_image_subsizes(). - Accept transposed dimensions when validating an
originalsideload. - Reset the stored EXIF orientation to 1 in finalize for both
originalandscaledsub-sizes, aswp_create_image_subsizes()does for its scale and rotate paths, soexif_orientationno longer reports the pre-rotation value once rotation has been applied. - Skip
original/scaledfinalize entries missing the file name so a malformed payload cannot blank out the main file metadata.
Includes a parity test asserting the client-side path produces the same attachment metadata (dimensions, orientation, original_image) as a classic server-side upload of the same EXIF-rotated fixture.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
## Summary
Builds on #11015. Adds dimension validation to the sideload endpoint.
validate_image_dimensions()private method toWP_REST_Attachments_Controllerwp/v2/media/<id>/sideloadendpointwp_getimagesize()call earlier insideload_item()to validate before metadata handling### Validation rules:
## Test plan
test_sideload_item_rejects_oversized_dimensions— uploads 640x480 image as thumbnail (150x150), expects 400 withrest_upload_dimension_mismatchtest_sideload_item_accepts_valid_dimensions— uploads 50x50 image as thumbnail, expects 200Corresponding Gutenberg PR: https://github.com/WordPress/gutenberg/pull/74903