WP Manifestindependent plugin directory
manifest / developer / wp-admin-utility

WordPress Admin Utility WP Registry grade D+. High-severity findings · 2 findingsWP RegistryHigh-severity findings · 2 findingsOpen the reportD+

Create admin pages and post types via declarative config files

★ 3stars
13kcomposer installs
v0.5.1latest · 8 years ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/dwalkr/wp-admin-utility/archive/refs/heads/master.zip

On Packagist as dwalkr/wp-admin-utility:

composer require dwalkr/wp-admin-utility
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

WordPress Admin Page Utility

wp-admin-utility installs as a plugin and provides an API for quickly setting up custom post types and options pages. Whereas other post type builders provide an admin interface for creating post types, this utility reads static configuration files to create post types via a declarative syntax.

Installation

composer require dwalkr/wp-admin-utility

Basic Usage

The PageCreator singleton is used to parse configuration files. It is made available on a custom hook named adminutility-pagecreator-init. The hook is triggered on after_setup_theme, so just be sure you add your callback before that event (plugins can use plugins_loaded and themes can just put their code directly in functions.php.)

Use the addPostType method to create post types, and addSettingsPage to create options pages.

<?php

add_action('adminutility-pagecreator-init', function($pageCreator){
  $pageCreator->addPostType('/path/to/config.yml');
});

Configuration Formats

Configuration files can be in yaml, json, or php format. When passing a PHP file to PageCreator, the file should return the configuration as an associative array.

Direct Array/Object Config

Instead of having PageCreator parse a configuration file, you can pass an array or PHP object containing the configuration instead of the path to a file. Use the FROM_ARRAY and FROM_OBJECT constants to tell PageCreator how to process the first method parameter.

<?php

$config = [
  'active' => true,
  'name' => 'specials',
  'public' => true
  //...
];
$pageCreator->addPostType($config, \dwalkr\WPAdminUtility\PageCreator::FROM_ARRAY);

Configuration API

Almost all options that can be passed into the register_post_type function can be added to the top-level config for a post type.

To understand how to set up meta boxes with custom fields, see the post type example.

To understand how to set up settings pages, see the settings page example.

Adding Custom Meta Boxes to Existing Post Types

To add a custom fields and meta boxes to an existing post type, just add a configuration file with the name property matching the existing post type. If the post type has already been registered, the rest of the top-level configuration is ignored and only metaboxes are added.

Releases

15 releases.

Tag
Published
v0.5.1 latest
Feb 26, 2018 8 years ago
Dec 6, 2017 8 years ago
Sep 15, 2017 9 years ago
Jun 28, 2017 9 years ago
May 19, 2017 9 years ago
May 19, 2017 9 years ago
May 19, 2017 9 years ago
May 18, 2017 9 years ago
May 10, 2017 9 years ago
Apr 25, 2017 9 years ago
Apr 13, 2017 9 years ago
Oct 24, 2016 10 years ago
Sep 11, 2016 10 years ago
Aug 1, 2016 10 years ago
Jun 1, 2016 10 years ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

D+ grade

Security

WordPress Admin Utility 0.3.1 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
0.3.1
Findings
2
Worst severity
high
Content hash
5a32013d5423d152537da8b8…

Findings

  • high Stored XSS in CPT list-table columns via unescaped post meta

    xss_stored

    When a field’s config sets listing: true, PostType::columns adds that field as a manage_edit-{cpt}_columns column and PostType::columns_content echo’s Field::getListingContent() with no escaping. getListingContent() returns raw get_post_meta($post->ID, $name, true). The write path is MetaBox::save on save_post: $_POST[$key] is passed through Field::prepareData() (identity for text/textarea/editor/checkbox) into update_post_meta with no sanitize_text_field / wp_kses_post and no unfiltered_html check. On a public CPT using default post capabilities (as in examples/post_type.yml), a Contributor or Author can plant <script> or editor-field HTML in that meta. Any user who can load edit.php?post_type={cpt} — including an Administrator reviewing all items — receives the payload in the table cell as HTML, not text. That is stored admin XSS from a role below manage_options. The listing flag is implemented in this plugin (not only in caller code); the official YAML example does not set it, but any site that enables the documented listing column hits this sink. Field views on the edit form itself do use esc_attr/esc_html; the list table is the exception.

    src/PostType.php:192-218

    Recommendation

    Escape list-table output (esc_html or wp_kses_post depending on field type). Sanitize on save: sanitize_text_field / sanitize_textarea_field for plain fields and wp_kses_post for editor fields unless the user has unfiltered_html. Do not echo raw get_post_meta into admin HTML.

  • medium Metaboxes hydrate from unsanitized $_GET['post'] with no capability check

    information_disclosure

    MetaBox::__construct runs from PostType::setupMetaBoxes() on init for every request after a CPT is registered. If $_GET['post'] is present it is passed straight to get_post_meta($post_id, $fieldData->name, true) with no absint, no current_user_can('edit_post'), and no post-type check, and that value becomes the Field object shown by display(). On post.php WordPress already authorized the same ID, so this is harmless. On post-new.php core never reads $_GET['post'] (it calls get_default_post_to_edit); a Contributor/Author who can create the CPT can open post-new.php?post_type={cpt}&post={victimId} and the metaboxes render the victim’s values for every configured key — including posts they cannot edit, other post types, and drafts. Field\Password::getFieldValue() decrypts AUTH_KEY-Blowfish ciphertext into the input value, so a password field becomes a secret oracle. This is a read IDOR, not a write (save_post still uses the new auto-draft ID). Subscriber cannot open post-new.php (create_posts). Unauthenticated users never see the metabox HTML.

    src/MetaBox.php:40-56

    Recommendation

    Load field values from get_the_ID() / the post being edited after core has authorized it, not from raw $_GET['post'] at init. If a request ID is used, absint() it and require current_user_can('edit_post', $post_id) and get_post_type($post_id) === the configured type before calling get_post_meta. On post-new.php leave values empty/default.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.