Make WordPress Core

Opened 6 weeks ago

Last modified 3 weeks ago

#64183 assigned defect (bug)

Mixed attachment permission when two posts are using it

Reported by: bor0's profile bor0 Owned by: johnjamesjacoby's profile johnjamesjacoby
Milestone: 7.0 Priority: normal
Severity: normal Version: 6.9
Component: REST API Keywords: has-patch has-unit-tests early
Focuses: rest-api Cc:

Description

When two posts share the same attachment—one with a draft status and one with a publish status—and the attachment’s post_parent is set to the draft post, the published post will incorrectly include the attachment in the _embed field. This causes a 401 Unauthorized response when the attachment is fetched via the REST API.

Observe:

bor0:~/dev/www$ DRAFT_POST_ID=$(wp post create --post_title="Draft Post" --post_status=draft --porcelain)
bor0:~/dev/www$ echo "Draft post ID: $DRAFT_POST_ID"
Draft post ID: 126

Now, let's add an attachment, which has post_parent set to that draft post:

bor0:~/dev/www$ convert -size 800x600 xc:blue /tmp/test-image.jpg 2>/dev/null || \
> echo "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" | base64 -d > /tmp/test-image.png
bor0:~/dev/www$ ATTACHMENT_ID=$(wp media import /tmp/test-image.png --post_id=$DRAFT_POST_ID --porcelain)
bor0:~/dev/www$ echo "Attachment ID: $ATTACHMENT_ID"
Attachment ID: 127

Next, create a post with status=publish and add this attachment as a thumbnail:

bor0:~/dev/www$ PUBLISHED_POST_ID=$(wp post create --post_title="Published Post" --post_status=publish --porcelain)
bor0:~/dev/www$ echo "Published post ID: $PUBLISHED_POST_ID"
Published post ID: 128
bor0:~/dev/www$ wp post meta add $PUBLISHED_POST_ID _thumbnail_id $ATTACHMENT_ID
Success: Added custom field.

Check all statuses:

bor0:~/dev/www$ echo "Draft post status: $(wp post get $DRAFT_POST_ID --field=post_status)"
Draft post status: draft
bor0:~/dev/www$ echo "Published post status: $(wp post get $PUBLISHED_POST_ID --field=post_status)"
Published post status: publish
bor0:~/dev/www$ echo "Attachment status: $(wp post get $ATTACHMENT_ID --field=post_status)"
Attachment status: inherit
bor0:~/dev/www$ echo "Attachment parent: $(wp post get $ATTACHMENT_ID --field=post_parent)"
Attachment parent: 126

Finally, observe:

bor0:~/dev/www$ curl -s "http://localhost:8080/wp-json/wp/v2/posts?_embed=1" | jq -r '.[] | "\(.id) - \(.status) - Featured: \(._links."wp:featuredmedia"[0].href // "none")"'
128 - publish - Featured: http://localhost:8080/wp-json/wp/v2/media/127
125 - publish - Featured: http://localhost:8080/wp-json/wp/v2/media/124
117 - publish - Featured: none
110 - publish - Featured: none
1 - publish - Featured: none
bor0:~/dev/www$ curl http://localhost:8080/wp-json/wp/v2/media/127
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":401}}

The published post should not expose the attachment via _embed if it inherits access restrictions from a draft parent. Alternatively, the media endpoint should not return 401 if it is embedded in a public post.

Attachments (1)

64183.patch (4.5 KB) - added by bor0 6 weeks ago.

Download all attachments as: .zip

Change History (4)

@bor0
6 weeks ago

#1 @bor0
6 weeks ago

  • Keywords has-patch has-unit-tests added

@SergeyBiryukov hi, me again :) would appreciate if you can 👀 this one

#2 @johnjamesjacoby
3 weeks ago

What a funny thing.

Patch looks good to me, and still applies cleanly to trunk at this time.

The published post should not expose the attachment via _embed if it inherits access restrictions from a draft parent. Alternatively, the media endpoint should not return 401 if it is embedded in a public post.

I can see how this could go either way, but I think I prefer the approach in your patch, unless or until a compelling reason to open it up reveals itself.

#3 @johnjamesjacoby
3 weeks ago

  • Keywords early added
  • Milestone changed from Awaiting Review to 7.0
  • Owner set to johnjamesjacoby
  • Status changed from new to assigned
Note: See TracTickets for help on using tickets.