WebDevStudios / WebDevStudios/custom-post-type-ui

CVE-2025-12826 fix regressed delegated CPT UI management

Open
#1,049 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
641
Forks
139
PR merge metrics
No merged PRs in 30d

Description

Summary

Since 1.18.1, CPT UI uses two different authorization models for the same management flow:

  • page access uses apply_filters( 'cptui_required_capabilities', 'manage_options' )
  • save/delete processing uses current_user_can( 'manage_options' )

As a result, a user granted CPT UI access through cptui_required_capabilities can open the management screens but cannot complete the default save/delete flow. This regression was introduced by the CVE-2025-12826 fix in 215779a5ac0c624f0dcf875e87305b4898d5bcf9.

Minimal PoC

Create an MU plugin:

wp-content/mu-plugins/cptui-cap-delegation-poc.php

<?php
add_filter( 'cptui_required_capabilities', static function () {
	return 'edit_pages';
} );

Test with a built-in WordPress Editor account:

  • Editor has edit_pages
  • Editor does not have manage_options

Reproduction

  1. Install and activate Custom Post Type UI 1.19.3.
  2. Add the MU plugin above.
  3. Log in as an Editor.
  4. Open wp-admin/admin.php?page=cptui_manage_post_types.
  5. Submit the default Add New form with a unique post type slug, for example editor_demo_cpt.
  6. Reload the screen or open CPT UI listings.
  7. Confirm that the post type was not created.

Taxonomy variant:

  1. Open wp-admin/admin.php?page=cptui_manage_taxonomies.
  2. Submit the default Add New form with a unique taxonomy slug and at least one associated post type.
  3. Reload the screen or open CPT UI listings.
  4. Confirm that the taxonomy was not created.

If the site already has CPT UI-managed objects, the same mismatch can be checked through the built-in Save and Delete actions on the existing edit screens.

Actual behavior

  • the delegated user can access the CPT UI management screen
  • the built-in form posts back into the default CPT UI request path
  • cptui_process_post_type() / cptui_process_taxonomy() return immediately on the hardcoded manage_options check
  • cptui_update_post_type() / cptui_update_taxonomy() are not reached
  • the object is not persisted
  • the normal success notice path is not scheduled

Expected behavior

The same capability model should be used for:

  • CPT UI page access
  • CPT UI save/delete processing

If delegated management is no longer supported after CVE-2025-12826, the public filter and UI flow should be aligned with that decision and should not expose editable forms to users who cannot submit them.

Code evidence

  • custom-post-type-ui.php
    Menu and submenu pages still use cptui_required_capabilities.
  • inc/post-types.php
    The default post type form is still rendered.
  • inc/post-types.php
    cptui_process_post_type() now requires manage_options before any save/delete branch.
  • inc/post-types.php
    Post type add requires a name; the default add path is otherwise valid.
  • inc/post-types.php
    Persistence happens only when cptui_update_post_type() reaches update_option( 'cptui_post_types', ... ).
  • inc/taxonomies.php
    The default taxonomy form is still rendered.
  • inc/taxonomies.php
    cptui_process_taxonomy() now requires manage_options before any save/delete branch.
  • inc/taxonomies.php
    Taxonomy add requires a name.
  • inc/taxonomies.php
    Taxonomy add also requires at least one associated post type.
  • inc/taxonomies.php
    Persistence happens only when cptui_update_taxonomy() reaches update_option( 'cptui_taxonomies', ... ).
  • inc/utility.php
    cptui_get_post_form_action() returns an empty action by default; the repository does not register an internal cptui_post_form_action override.
  • CHANGELOG.md
    1.5.1 explicitly documents the move to filtered capability-based menu access.
  • inc/support.php
    The current support page still documents capability customization as a supported customization topic.

Requested resolution

Use the same CPT UI management capability in both layers:

  • page access
  • save/delete processing

That preserves the CVE-2025-12826 fix while removing the current UI/processing authorization mismatch.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with cptui_process_post_type() in inc/post-types.php and cptui_process_taxonomy() in inc/taxonomies.php, then compare their checks with cptui_required_capabilities in custom-post-type-ui.php. Reproduce the Editor-account flow from the issue for both post types and taxonomies; done means delegated users can complete the supported save/delete actions without weakening the CVE fix.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
authorization, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.