WordPress allows posts to have a parent. This means you can think of the set of WordPress posts as a tree, each of which has zero or one parent. Here, we use an arrow that points from its child to its parent:

WordPress, however, does not allow cycles. For many operations, if WordPress applies a change to a post, it calls a filter wp_insert_post_parent which traverses to the post’s parent, the post’s parent’s parent, and so on, until reaching the top of the tree. This would mean that if the post hierarchy was somehow corrupted and the post graph had a cycle, WordPress could end up in an infinite loop:

This is relevant to page hierarchies. If you made a post a parent of itself, it could cause many issues.

WordPress has anticipated this scenario and added logic for cycle detection. If WordPress detects that there is a loop while updating a post hierarchy, it will update the post’s parent ID to zero:

wp_update_post(
    array(
        'ID'          => B,
        'post_parent' => 0,
    )
);

This is a different call to the earlier wp_update_post. Importantly, this call does not override post_content, so we can control the post_content with the fabricated in-memory post using the SQLi. Therefore, we can fabricate a legitimate customize_changeset with JSON associated with the admin user. This allows us to make changes to other posts as the administrator. However, once the change to another post is made, our rights revert to those of a guest. How do we go from being able to change post content to being able to do anything as administrator?

=⇒ Đến đây phải nhờ vào thằng hook.