WP Manifestindependent plugin directory
manifest / updates / wp-upgrade-task-runner

Upgrade Task Runner WP Registry grade B. Medium-severity findings · 1 findingWP RegistryMedium-severity findings · 1 findingOpen the reportB

Register custom migration tasks that can be scheduled from the plugin settings dashboard in the admin and run as a cron job.

★ 4stars
18kcomposer installs
2.8.0latest · 2 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/thefrosty/wp-upgrade-task-runner/archive/refs/heads/develop.zip

On Packagist as thefrosty/wp-upgrade-task-runner:

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

WordPress Upgrade Task Runner

WP Upgrade Task Runner

Register custom migration tasks that can be triggered from a dashboard in the admin and run via AJAX.

Requirements

PHP >= 8.1
WordPress >= 6.2

The required WordPress version will always be the most recent point release of the previous major release branch.

For both PHP and WordPress requirements, although this library may work with a version below the required versions, they will not be supported and any compatibility is entirely coincidental.

Installation

To install this library, use Composer:

composer require thefrosty/wp-upgrade-task-runner:^2

Getting Started

If a new task is needed, there are only two required steps that are needed.

  1. A class needs to be created and this class needs to extend the AbstractTaskRunner class. See the ExampleMigrationTask example class.
  2. Register the new task class via the TaskLoader::REGISTER_TASKS_TAG filter:
    
    use TheFrosty\WpUpgradeTaskRunner\Tasks\TaskLoader;

\add_filter(TaskLoader::REGISTER_TASKS_TAG, static function(array $tasks): array { $tasks[] = new \Project\SomeCustomTask(); return $tasks; });



### The task class

When a class is added, it needs to have a few pre-defined class values. Both the DATE and TITLE constant are required
to be unique. These are what registers a one off cron task when manually _running_ the task from the admin page.

### The `TaskLoader`

Add the new class as a property in the `TaskLoader` class and instantiate it in the `register_tasks` method (just like
the `ExampleMigrationTask`).

### CLI

Run all registered tasks (not already run) via wp-cli: `$ wp upgrade-task-runner`.

#### CLI OPTIONS
     [--task=<class>] : The fully qualified registered task to run.
     [--user=<id>] : The user ID to associate with running said task(s).

Releases

21 releases.

Tag
Published
2.8.0 latest
Mar 22, 2024 2 years ago
Apr 18, 2023 3 years ago
Mar 1, 2022 4 years ago
Nov 2, 2021 4 years ago
Nov 1, 2021 4 years ago
Jan 4, 2021 5 years ago
Dec 16, 2020 5 years ago
Sep 25, 2020 6 years ago
Aug 13, 2020 6 years ago
Aug 11, 2020 6 years ago
Apr 21, 2020 6 years ago
Jan 31, 2020 6 years ago
Jan 10, 2020 6 years ago
Dec 4, 2019 6 years ago
Nov 26, 2019 6 years ago
Aug 1, 2019 7 years ago
Mar 7, 2019 7 years ago
Mar 7, 2019 7 years ago
Mar 7, 2019 7 years ago
Mar 7, 2019 7 years ago
Mar 6, 2019 7 years ago

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

B grade

Security

Upgrade Task Runner 2.8.0 · audited by WP Registry

Medium-severity findings.

1 medium
Audited release
2.8.0
Findings
1
Worst severity
medium
Content hash
e2005eeea3d5f2e16af47223…

Findings

  • medium Broken AJAX nonce allows CSRF of pending migration tasks

    csrf

    wp_ajax_wp_upgrade_schedule_task_event (no nopriv twin) is the UI path for Run. After a Reflection invoke of TaskLoader::registerFields, the handler requires POST _task_runner_execute_nonce and item to exist (any values), then calls check_ajax_referer(getNonceKeyValue($item), false, false). Two defects make that check a no-op: (1) the second argument false means WordPress reads _ajax_nonce/_wpnonce, never the _task_runner_execute_nonce field upgrades.js actually sends; (2) a truthy wp_verify_nonce result (1 or 2) is treated as failure ('bad nonce'), so a missing/invalid nonce continues. current_user_can('manage_options') still applies, so Subscriber/customer cannot fire it, but a logged-in administrator can be CSRF'd with a cross-site POST that includes dummy _task_runner_execute_nonce plus item. triggerTaskRunnerScheduleEvent then array_search()es item against registered titles; a miss returns false, and isset($fields[false]) is isset($fields[0]) in PHP, so even an unknown item schedules the first still-pending task via wp_schedule_single_event. When cron runs, that TaskRunnerInterface::dispatch() performs whatever DB migration the site registered (the plugin's entire purpose) and complete() writes option wp_upgrade_task_runner. The parallel GET maybeExecute path does use wp_verify_nonce correctly, so this is specifically the AJAX/CSRF hole. Observable: after the admin CSRF, wp_get_scheduled_event(FQCN) is set and the task later marks itself complete in wp_upgrade_task_runner.

    src/Upgrade.php:223-278

    Recommendation

    Invert the nonce check (fail closed): if (!check_ajax_referer($this->getNonceKeyValue($item), self::NONCE_NAME, false)) { wp_send_json_error(...); }. Pass NONCE_NAME so the posted _task_runner_execute_nonce is the value verified. Reject when array_search returns false (strict $key === false) instead of treating it as index 0. Also call current_user_can(apply_filters(self::TAG_UPGRADE_TASKS_CAP, 'promote_users')) on maybeExecute so the GET path matches the UI cap.

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.