Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/premmerce-redirect-manager/premmerce-redirect.php
+++ b/premmerce-redirect-manager/premmerce-redirect.php
@@ -9,7 +9,7 @@
* Plugin Name: Premmerce Redirect Manager
* Plugin URI: https://premmerce.com/woocommerce-redirect-manager/
* Description: The Premmerce Redirect Manager enables you to create 301 and 302 redirects and to set up the automatic redirects for the deleted products in the WooCommerce store.
- * Version: 1.0.12
+ * Version: 1.0.13
* Author: Premmerce
* Author URI: https://premmerce.com
* License: GPL-2.0+
--- a/premmerce-redirect-manager/src/Admin/Admin.php
+++ b/premmerce-redirect-manager/src/Admin/Admin.php
@@ -248,8 +248,20 @@
*/
public function getPostsByString()
{
+ if (! current_user_can('manage_options')) {
+ wp_send_json_error(array( 'message' => __('You do not have permission to perform this action.', 'premmerce-redirect') ), 403);
+ }
+
+ if (! isset($_POST['_wpnonce']) || ! wp_verify_nonce(wp_unslash($_POST['_wpnonce']), 'premmerce_redirect_search')) {
+ wp_send_json_error(array( 'message' => __('Security check failed.', 'premmerce-redirect') ), 403);
+ }
+
if (isset($_POST['type'])) {
- $objects = $this->model->getPostsByString($_POST);
+ $data = array(
+ 'type' => sanitize_text_field($_POST['type']),
+ 's' => isset($_POST['s']) ? sanitize_text_field($_POST['s']) : '',
+ );
+ $objects = $this->model->getPostsByString($data);
wp_send_json($objects);
}
@@ -327,6 +339,9 @@
{
wp_enqueue_script('select2', $this->fileManager->locateAsset('admin/js/select2.min.js'));
wp_enqueue_script('premmerce-redirect', $this->fileManager->locateAsset('admin/js/premmerce-redirect.js'));
+ wp_localize_script('premmerce-redirect', 'premmerceRedirect', array(
+ 'nonce' => wp_create_nonce('premmerce_redirect_search'),
+ ));
wp_enqueue_style('select2', $this->fileManager->locateAsset('admin/css/select2.min.css'));
wp_enqueue_style('premmerce-redirect', $this->fileManager->locateAsset('admin/css/premmerce-redirect.css'));
--- a/premmerce-redirect-manager/src/Admin/RedirectsTable.php
+++ b/premmerce-redirect-manager/src/Admin/RedirectsTable.php
@@ -139,7 +139,7 @@
$data = $this->api->getRedirects();
} else {
$data = $this->api->getRedirects(false);
-// ['redirect_type', 'NOT IN', ['product', 'product_category']]
+ // ['redirect_type', 'NOT IN', ['product', 'product_category']]
}
if (isset($_POST['s']) && $_POST['s']) {
--- a/premmerce-redirect-manager/src/RedirectModel.php
+++ b/premmerce-redirect-manager/src/RedirectModel.php
@@ -166,18 +166,25 @@
*/
public function getPostsByString($data)
{
- if (in_array($data['type'], array('product', 'post', 'page'))) {
+ $allowed_post_types = array( 'product', 'post', 'page' );
+ $allowed_taxonomies = array( 'product_cat', 'category' );
+
+ if (in_array($data['type'], $allowed_post_types, true)) {
$objects = (new WP_Query(array(
- 's' => isset($data['s'])? $data['s'] : '',
- 'post_type' => $data['type'],
- 'numberposts' => 10,
+ 's' => isset($data['s']) ? $data['s'] : '',
+ 'post_type' => $data['type'],
+ 'posts_per_page' => 10,
+ 'has_password' => false,
+ 'post_status' => 'publish',
)))->posts;
- } else {
+ } elseif (in_array($data['type'], $allowed_taxonomies, true)) {
$objects = get_terms(array(
'hide_empty' => false,
- 'search' => isset($data['s'])? $data['s'] : '',
+ 'search' => isset($data['s']) ? $data['s'] : '',
'taxonomy' => $data['type'],
));
+ } else {
+ $objects = array();
}
return $objects;
--- a/premmerce-redirect-manager/src/RedirectPlugin.php
+++ b/premmerce-redirect-manager/src/RedirectPlugin.php
@@ -65,6 +65,7 @@
*/
public function useRedirect()
{
+
global $wp;
$uri = '/' . $wp->request;
@@ -105,6 +106,7 @@
}
if ($url) {
+
if ($_SERVER['QUERY_STRING']) {
// get query args from the redirection target
$url_query = wp_parse_url($url, PHP_URL_QUERY);
--- a/premmerce-redirect-manager/vendor/autoload.php
+++ b/premmerce-redirect-manager/vendor/autoload.php
@@ -14,12 +14,9 @@
echo $err;
}
}
- trigger_error(
- $err,
- E_USER_ERROR
- );
+ throw new RuntimeException($err);
}
require_once __DIR__ . '/composer/autoload_real.php';
-return ComposerAutoloaderInit1aa059d654e1d610545d4e5ff8bd5f67::getLoader();
+return ComposerAutoloaderInitde07ce47490c4cc28cdaafe6d3015c14::getLoader();
--- a/premmerce-redirect-manager/vendor/composer/InstalledVersions.php
+++ b/premmerce-redirect-manager/vendor/composer/InstalledVersions.php
@@ -27,12 +27,23 @@
class InstalledVersions
{
/**
+ * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
+ * @internal
+ */
+ private static $selfDir = null;
+
+ /**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
+ * @var bool
+ */
+ private static $installedIsLocalDir;
+
+ /**
* @var bool|null
*/
private static $canGetVendors;
@@ -309,6 +320,24 @@
{
self::$installed = $data;
self::$installedByVendor = array();
+
+ // when using reload, we disable the duplicate protection to ensure that self::$installed data is
+ // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
+ // so we have to assume it does not, and that may result in duplicate data being returned when listing
+ // all installed packages for example
+ self::$installedIsLocalDir = false;
+ }
+
+ /**
+ * @return string
+ */
+ private static function getSelfDir()
+ {
+ if (self::$selfDir === null) {
+ self::$selfDir = strtr(__DIR__, '\', '/');
+ }
+
+ return self::$selfDir;
}
/**
@@ -322,19 +351,27 @@
}
$installed = array();
+ $copiedLocalDir = false;
if (self::$canGetVendors) {
+ $selfDir = self::getSelfDir();
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+ $vendorDir = strtr($vendorDir, '\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
- $installed[] = self::$installedByVendor[$vendorDir] = $required;
- if (null === self::$installed && strtr($vendorDir.'/composer', '\', '/') === strtr(__DIR__, '\', '/')) {
- self::$installed = $installed[count($installed) - 1];
+ self::$installedByVendor[$vendorDir] = $required;
+ $installed[] = $required;
+ if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
+ self::$installed = $required;
+ self::$installedIsLocalDir = true;
}
}
+ if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
+ $copiedLocalDir = true;
+ }
}
}
@@ -350,7 +387,7 @@
}
}
- if (self::$installed !== array()) {
+ if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
--- a/premmerce-redirect-manager/vendor/composer/autoload_real.php
+++ b/premmerce-redirect-manager/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInit1aa059d654e1d610545d4e5ff8bd5f67
+class ComposerAutoloaderInitde07ce47490c4cc28cdaafe6d3015c14
{
private static $loader;
@@ -22,12 +22,12 @@
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInit1aa059d654e1d610545d4e5ff8bd5f67', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInitde07ce47490c4cc28cdaafe6d3015c14', 'loadClassLoader'), true, true);
self::$loader = $loader = new ComposerAutoloadClassLoader(dirname(__DIR__));
- spl_autoload_unregister(array('ComposerAutoloaderInit1aa059d654e1d610545d4e5ff8bd5f67', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInitde07ce47490c4cc28cdaafe6d3015c14', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
- call_user_func(ComposerAutoloadComposerStaticInit1aa059d654e1d610545d4e5ff8bd5f67::getInitializer($loader));
+ call_user_func(ComposerAutoloadComposerStaticInitde07ce47490c4cc28cdaafe6d3015c14::getInitializer($loader));
$loader->register(true);
--- a/premmerce-redirect-manager/vendor/composer/autoload_static.php
+++ b/premmerce-redirect-manager/vendor/composer/autoload_static.php
@@ -4,10 +4,10 @@
namespace ComposerAutoload;
-class ComposerStaticInit1aa059d654e1d610545d4e5ff8bd5f67
+class ComposerStaticInitde07ce47490c4cc28cdaafe6d3015c14
{
public static $prefixLengthsPsr4 = array (
- 'P' =>
+ 'P' =>
array (
'Premmerce\SDK\' => 14,
'Premmerce\Redirect\' => 19,
@@ -15,11 +15,11 @@
);
public static $prefixDirsPsr4 = array (
- 'Premmerce\SDK\' =>
+ 'Premmerce\SDK\' =>
array (
0 => __DIR__ . '/..' . '/premmerce/wordpress-sdk/src',
),
- 'Premmerce\Redirect\' =>
+ 'Premmerce\Redirect\' =>
array (
0 => __DIR__ . '/../..' . '/src',
),
@@ -32,9 +32,9 @@
public static function getInitializer(ClassLoader $loader)
{
return Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInit1aa059d654e1d610545d4e5ff8bd5f67::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInit1aa059d654e1d610545d4e5ff8bd5f67::$prefixDirsPsr4;
- $loader->classMap = ComposerStaticInit1aa059d654e1d610545d4e5ff8bd5f67::$classMap;
+ $loader->prefixLengthsPsr4 = ComposerStaticInitde07ce47490c4cc28cdaafe6d3015c14::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitde07ce47490c4cc28cdaafe6d3015c14::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInitde07ce47490c4cc28cdaafe6d3015c14::$classMap;
}, null, ClassLoader::class);
}
--- a/premmerce-redirect-manager/vendor/composer/installed.php
+++ b/premmerce-redirect-manager/vendor/composer/installed.php
@@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'premmerce/premmerce-redirect',
- 'pretty_version' => 'dev-master',
- 'version' => 'dev-master',
- 'reference' => 'c99bb34d37f2228ff217eed00a8aceff549c7f75',
+ 'pretty_version' => '1.0.13',
+ 'version' => '1.0.13.0',
+ 'reference' => '1432f8c7efeb7cf444d00d909a50a54ef1446d70',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -11,9 +11,9 @@
),
'versions' => array(
'premmerce/premmerce-redirect' => array(
- 'pretty_version' => 'dev-master',
- 'version' => 'dev-master',
- 'reference' => 'c99bb34d37f2228ff217eed00a8aceff549c7f75',
+ 'pretty_version' => '1.0.13',
+ 'version' => '1.0.13.0',
+ 'reference' => '1432f8c7efeb7cf444d00d909a50a54ef1446d70',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),