[wp-trac] [WordPress Trac] #64183: Mixed attachment permission when two posts are using it
WordPress Trac
noreply at wordpress.org
Mon Nov 3 10:33:10 UTC 2025
#64183: Mixed attachment permission when two posts are using it
--------------------------+-----------------------------
Reporter: bor0 | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: REST API | Version: trunk
Severity: normal | Keywords:
Focuses: rest-api |
--------------------------+-----------------------------
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.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/64183>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list