WP Manifestindependent plugin directory
manifest / performance / wp-stash

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

Bridge between WordPress and StashPHP, providing a PSR6-compliant caching system for WordPress

★ 54stars
v3.4.1latest · 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/inpsyde/wp-stash/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

WP Stash is a bridge between StashPHP and WP's object caching drop-in support. It enables APCu, Redis, SQLite, Memcached, and Filesystem caches, stampede protection, and group invalidation.

After installing, it will copy an object-cache.php file to wp-content/ which will delegate all cache calls to its mu-plugin folder. From there, it will interface with StashPHP.

Installation

This plugin is a Composer package that will be installed as a wordpress-muplugin. As such, there are a few things to note when attempting to install it. Usually, MU-Plugins are single PHP files, sometimes accompanied by a subfolder containing more code. Since WP-Stash assumes it's living in a subfolder, it contains a lot of other dev-related stuff in its root folder.

For WP to pick up WP-Stash as an MU-Plugin, you have to do one of the following:

Composer

As a first step, simply require the package via composer

composer require inpsyde/wp-stash

Since this package will get installed in a subfolder. WordPress will not automatically load it on its own. The following solutions exist:

WP Starter

If you are using the awesome WP Starter package, then everything will work automatically. It contains an MU-Loader which will take care of loading WP Stash. Note that you MUST NOT use WPStarter's drop-in functionality to copy object-cache.php on build time! WPStash must place the drop-in file on its own. If you want to trigger WP-Stash to create the drop-in file just run a command like wp plugin list.

WP Must-Use Plugin Loader

WP Must-Use Plugin Loader is a standalone composer package that will take care of loading mu-plugins for you. Just require the package and follow the usage instructions from the link to set it up.

Without Composer

Direct upload

You can technically use WP-Stash by simply extracting all files into the wp-content/mu-plugins/ folder. However, this is pretty dirty and we strongly discourage doing so. Instead, please look at the WordPress Codex on MU-Plugins to find solutions for loading mu-plugins from folders.

The easiest solution is to add a wp-content/mu-plugins/wp-stash.php file and put the following in it:

<?php

require __DIR__ . '/wp-stash/wp-stash.php';

Configuration

You can configure WP Stash globally in the configuration file of your WordPress instance. It is possible to set a Cache Driver and configuration values for it.

Please consult the the StashPHP documentation for information on Driver configuration

The following constants (or environment variables) can be used for configuring WP Stash:

WP_STASH_DRIVER - FQCN: The class name of the Stash driver you want to use. Will fall back to Ephemeral (pure memory cache without persistence) if unset or invalid. Available drivers are:

  • \Stash\Driver\Apc
  • \Stash\Driver\FileSystem
  • \Stash\Driver\Sqlite
  • \Stash\Driver\Memcache (not Memcached)
  • \Stash\Driver\Redis
  • \Stash\Driver\Ephermal
  • \Stash\Driver\Composite

WP_STASH_DRIVER_ARGS - string: Driver constructor args as a serialized array or JSON.

WP_STASH_IN_MEMORY_CACHE - bool: If enabled, keeps an in-memory version of the cache in sync. This enhances performance during a single request. Default true.

WP_STASH_PURGE_INTERVAL - integer: WP Stash runs scheduled maintenance actions on the configured cache driver every 12 hours by default. You can configure a different interval here. Default 3600*12.

WP_STASH_BYPASS - bool: Allows temporarily disabling WP-Stash and falling back to the core WP system.

Environment variables

If you work with Composer-based environments like WPStarter you might want to use environment variables right away. Here are some examples:

Caching with APC:

WP_STASH_DRIVER=\Stash\Driver\Apc
WP_STASH_DRIVER_ARGS='{"ttl":3600}'

Caching to filesystem in the /var/www/cache folder:

WP_STASH_DRIVER=\Stash\Driver\FileSystem
WP_STASH_DRIVER_ARGS='{"path":"\/var\/www\/cache","dirSplit":1}'

Caching with a memcached server using the memcached host name (e.g. in DDEV):

WP_STASH_DRIVER=\Stash\Driver\Memcache
WP_STASH_DRIVER_ARGS='{"servers":["memcached","11211"]}'

Caching with a Redis server using the redis host name (e.g. in DDEV):

WP_STASH_DRIVER=\Stash\Driver\Redis
WP_STASH_DRIVER_ARGS='{"servers":[{"server":"redis", "port":6379}]}'

Don't cache persistently at all (cache lives only within the script lifetime):

WP_STASH_DRIVER=\Stash\Driver\Ephermal

wp-config.php

define('WP_STASH_DRIVER',  '\Stash\Driver\Apc');
define('WP_STASH_DRIVER_ARGS', serialize(['ttl' => 3600]));

wp-cli

WP Stash has the following CLI commands:

wp stash flush: An improved version of wp cache flush. This command ensures that wp_cache_flush() is called by the web server, not the CLI process (which might run as a different user, or with a different configuration). This ensures compatibility with all caching back-ends.

wp stash purge: Some drivers require that maintenance action be performed regularly. The FileSystem and SQLite drivers, for example, need to remove old data as they can't do it automatically. While this is automatically performed via WP cron, you can trigger the process manually with this command.

Ensure your persistent cache works as expected

To test if your persistent cache works you can use WP-CLI. First, log in to your WordPress site with your user. Now run the following command in WP-CLI:

wp cache get {your-user-ID} users
(object) array(
   'ID' => '1',
   'user_login' => 'you',
   'user_pass' => '$P$BfWcDiF3YcFfnIMAGUmiYOuxD/6eaY0',
   'user_nicename' => 'you',
   'user_email' => 'you@yourdomain.com',
   'user_url' => 'https://yourdomain.com',
   'user_registered' => '2018-02-09 21:44:34',
   'user_activation_key' => '',
   'user_status' => '0',
   'display_name' => 'Your Name',
   'spam' => '0',
   'deleted' => '0',
)

This has some limitations and might not work on some server setups depending on whether the web server and your console user are the same.

In that case, you could check if common transients are stored in the cache. First, delete all transients just in case there are some left:

wp transient delete --network --all
Success: No transients found.
Warning: Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.

Now clear the cache

wp stash flush

Now check for updates (to fill the transient) and request the cache object:

wp core check-update
Success: WordPress is at the latest version.
wp cache get update_core site-transient
(object) array(
   'updates' => 
  array (
    0 => 
    (object) array(
       'response' => 'latest',
...

Development

This package ships a DDEV configuration containing a complete WordPress installation.

To get started, run

ddev start

Then install WordPress with the following command:

ddev orchestrate

Now you can visit https://wp-stash.ddev.site/ and log in:

  • User: admin
  • Password: admin

This package is free software distributed under the terms of the GNU General Public License version 2 or (at your option) any later version. For the full license, see LICENSE.

Releases

13 releases.

Tag
Published
v3.4.1 latest
Aug 9, 2024 2 years ago
Jun 16, 2023 3 years ago
Dec 12, 2022 3 years ago
Aug 15, 2022 4 years ago
Jul 22, 2022 4 years ago
Nov 9, 2020 5 years ago
Oct 30, 2020 5 years ago
Oct 16, 2020 6 years ago
Oct 16, 2020 6 years ago
Jul 15, 2019 7 years ago
Dec 7, 2018 7 years ago
Oct 19, 2018 8 years ago
Jan 19, 2018 8 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

WP Stash 1.0 · audited by WP Registry

Medium-severity findings.

1 medium
Audited release
1.0
Findings
1
Worst severity
medium
Content hash
08d495d43f69776d839b95d7…

Findings

  • medium Subscriber+ object-cache flush via admin-post with nonce but no capability check

    missing_capability

    Controller::init() registers admin_post_purge_cache → CacheFlusher::flush_cache and admin_bar_menu → AdminBarMenu::render with no capability argument. render() always adds a 'Flush Object Cache' item whose href is wp_nonce_url(..., 'purge_cache'), so every logged-in user who can load wp-admin (Subscribers included, via profile.php) receives a usable nonce. flush_cache() only reads _wpnonce from GET and calls wp_verify_nonce; it never calls current_user_can. A Subscriber can therefore wipe the site-wide persistent object cache (wp_cache_flush → Stash pool clear). Impact is availability and cache integrity (DB stampede, transient/rate-limit reset), not RCE or data write, so this is medium rather than high. WordPress core and typical object-cache UIs restrict flush to manage_options.

    src/Admin/CacheFlusher.php:34-46

    Recommendation

    Require current_user_can('manage_options') (or a dedicated cap) in flush_cache() before wp_cache_flush(), and skip adding the admin-bar item unless the current user has that capability. Do not treat a nonce as authorization.

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.