Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/bit-smtp/backend/app/Config.php
+++ b/bit-smtp/backend/app/Config.php
@@ -22,7 +22,7 @@
public const VAR_PREFIX = 'bit_smtp_';
- public const VERSION = '1.2.2';
+ public const VERSION = '1.2.3';
public const DB_VERSION = '1.1';
@@ -58,7 +58,7 @@
return plugin_dir_path(self::get('MAIN_FILE'));
case 'SITE_URL':
- $parsedUrl = parse_url(get_admin_url());
+ $parsedUrl = wp_parse_url(get_admin_url());
$siteUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
$siteUrl .= empty($parsedUrl['port']) ? null : ':' . $parsedUrl['port'];
@@ -72,7 +72,7 @@
return rest_url('/' . self::SLUG . '/v' . self::API_VERSION);
case 'ROOT_URI':
- return set_url_scheme(plugins_url('', self::get('MAIN_FILE')), parse_url(home_url())['scheme']);
+ return set_url_scheme(plugins_url('', self::get('MAIN_FILE')), wp_parse_url(home_url())['scheme']);
case 'ASSET_URI':
return self::get('ROOT_URI') . '/assets';
--- a/bit-smtp/backend/app/HTTP/Middleware/NonceCheckerMiddleware.php
+++ b/bit-smtp/backend/app/HTTP/Middleware/NonceCheckerMiddleware.php
@@ -2,7 +2,6 @@
namespace BitAppsSMTPHTTPMiddleware;
-use BitAppsSMTPConfig;
use BitAppsSMTPDepsBitAppsWPKitHttpRequestRequest;
use BitAppsSMTPDepsBitAppsWPKitHttpResponse;
use BitAppsSMTPDepsBitAppsWPKitUtilsCapabilities;
@@ -11,10 +10,6 @@
{
public function handle(Request $request, ...$params)
{
- if (!$request->has('_ajax_nonce') || !wp_verify_nonce(sanitize_key($request->_ajax_nonce), Config::VAR_PREFIX . 'nonce')) {
- return Response::error('Invalid token')->httpStatus(411);
- }
-
if (!Capabilities::check('manage_options')) {
return Response::error([])->message('unauthorized access');
}
--- a/bit-smtp/backend/app/Plugin.php
+++ b/bit-smtp/backend/app/Plugin.php
@@ -165,6 +165,7 @@
try {
MigrationHelper::migrate(InstallerProvider::migration());
} catch (Exception $e) {
+ //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log -- we want to log this error
error_log('BIT SMTP Migration Error: ' . $e->getMessage());
}
}
--- a/bit-smtp/backend/app/Providers/HookProvider.php
+++ b/bit-smtp/backend/app/Providers/HookProvider.php
@@ -32,6 +32,7 @@
&& RequestType::is(RequestType::API)
) {
$router = new Router(RequestType::API, Config::SLUG, 'v' . Config::API_VERSION);
+ $router->setMiddlewares(Plugin::instance()->middlewares());
include $this->_pluginBackend . 'hooks' . DIRECTORY_SEPARATOR . 'api.php';
$router->register();
--- a/bit-smtp/backend/app/Views/EmailTemplate.php
+++ b/bit-smtp/backend/app/Views/EmailTemplate.php
@@ -249,7 +249,7 @@
<tr>
<td class="content-cell" align="center">
<p class="sub align-center">
- © ' . date('Y') . ' Bit SMTP Plugin. All rights reserved.
+ © ' . gmdate('Y') . ' Bit SMTP Plugin. All rights reserved.
</p>
<p class="sub align-center">
This is an automated email sent from your WordPress site using the Bit SMTP plugin.
@@ -302,7 +302,7 @@
Bit Apps Team
----------------------------------------
-© " . date('Y') . ' Bit SMTP Plugin. All rights reserved.
+© " . gmdate('Y') . ' Bit SMTP Plugin. All rights reserved.
This is an automated email sent from your WordPress site using the Bit SMTP plugin.
';
}
--- a/bit-smtp/backend/hooks/api.php
+++ b/bit-smtp/backend/hooks/api.php
@@ -1,14 +1,14 @@
<?php
+if (!defined('ABSPATH')) {
+ exit;
+}
+
use BitAppsSMTPDepsBitAppsWPKitHttpRouterRoute;
use BitAppsSMTPHTTPControllersLogController;
use BitAppsSMTPHTTPControllersSMTPController;
use BitAppsSMTPHTTPControllersTelemetryPopupController;
-if (!defined('ABSPATH')) {
- exit;
-}
-
Route::group(function () {
Route::post('mail/config/save', [SMTPController::class, 'saveMailConfig']);
Route::get('mail/config/get', [SMTPController::class, 'index']);
--- a/bit-smtp/bit_smtp.php
+++ b/bit-smtp/bit_smtp.php
@@ -1,10 +1,13 @@
<?php
+if (! defined('ABSPATH')) {
+ exit;
+}
/**
* Plugin Name: Bit SMTP
* Plugin URI: https://www.bitapps.pro/bit-smtp
* Description: Send email via SMTP using BIT SMTP plugin by Bit Apps
- * Version: 1.2.2
+ * Version: 1.2.3
* Author: Bit Apps
* Author URI: https://bitapps.pro
* Text Domain: bit-smtp
--- a/bit-smtp/vendor/bitapps/wp-kit/src/Http/Request/Request.php
+++ b/bit-smtp/vendor/bitapps/wp-kit/src/Http/Request/Request.php
@@ -197,6 +197,10 @@
public function validate($rules, $messages = null, $attributeLabels = null)
{
+ if (count($this->files()) > 0) {
+ $this->attributes = array_merge($this->attributes, $this->files());
+ }
+
$validator = $this->make($this->attributes, $rules, $messages, $attributeLabels);
if ($validator->fails()) {
--- a/bit-smtp/vendor/bitapps/wp-validator/src/ErrorBag.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/ErrorBag.php
@@ -1,5 +1,4 @@
<?php
-
namespace BitAppsSMTPDepsBitAppsWPValidator;
class ErrorBag
@@ -17,7 +16,7 @@
$defaultPlaceholders = [
'attribute' => $role->getInputDataContainer()->getAttributeLabel(),
- 'value' => $role->getInputDataContainer()->getAttributeValue(),
+ 'value' => $role->getInputDataContainer()->getAttributeValue(),
];
$placeholders = array_merge($paramValues, $defaultPlaceholders);
@@ -51,7 +50,7 @@
return $message;
}
- public function getErrors($field = null)
+ public function getErrors()
{
return $this->errors;
}
@@ -59,9 +58,9 @@
public function hasErrors($field = null): bool
{
if ($field === null) {
- return !empty($this->errors);
+ return ! empty($this->errors);
}
- return isset($this->errors[$field]) && !empty($this->errors[$field]);
+ return isset($this->errors[$field]) && ! empty($this->errors[$field]);
}
}
--- a/bit-smtp/vendor/bitapps/wp-validator/src/Exception/InvalidArgumentException.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/Exception/InvalidArgumentException.php
@@ -8,7 +8,7 @@
{
- public function __construct($ruleName, $parameterCount, $code = 0, Exception $previous = null)
+ public function __construct($ruleName, $parameterCount, $code = 0, ?Exception $previous = null)
{
parent::__construct(sprintf("Validation rule %s requires at least %d parameters", $ruleName, $parameterCount), $code, $previous);
}
--- a/bit-smtp/vendor/bitapps/wp-validator/src/Exception/MethodNotFoundException.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/Exception/MethodNotFoundException.php
@@ -7,7 +7,7 @@
class MethodNotFoundException extends Exception
{
- public function __construct($sanitizationMethod, $code = 0, Exception $previous = null)
+ public function __construct($sanitizationMethod, $code = 0, ?Exception $previous = null)
{
parent::__construct(sprintf("Unsupported sanitization method: %s.", $sanitizationMethod), $code, $previous);
}
--- a/bit-smtp/vendor/bitapps/wp-validator/src/Exception/RuleErrorException.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/Exception/RuleErrorException.php
@@ -7,7 +7,7 @@
class RuleErrorException extends Exception
{
- public function __construct($ruleName, $code = 0, Exception $previous = null)
+ public function __construct($ruleName, $code = 0, ?Exception $previous = null)
{
parent::__construct(sprintf("Unsupported validation rule: %s.", $ruleName), $code, $previous);
}
--- a/bit-smtp/vendor/bitapps/wp-validator/src/InputDataContainer.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/InputDataContainer.php
@@ -28,7 +28,7 @@
public function getAttributeValue($key = null)
{
- $keys = explode('.', trim($this->attributeKey, '[]'));
+ $keys = explode('.', trim($this->attributeKey ?? '', '[]'));
$data = $this->data;
@@ -61,4 +61,14 @@
return $this->data;
}
+ public function setAttributeValue($value): void
+ {
+ $keys = explode('.', trim($this->attributeKey ?? '', '[]'));
+
+ if (count($keys) > 1) {
+ $this->setNestedElement($this->data, $keys, $value);
+ } else {
+ $this->data[$this->attributeKey] = $value;
+ }
+ }
}
--- a/bit-smtp/vendor/bitapps/wp-validator/src/SanitizationMethods.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/SanitizationMethods.php
@@ -1,74 +1,59 @@
<?php
-
namespace BitAppsSMTPDepsBitAppsWPValidator;
trait SanitizationMethods
{
- protected function sanitizeEmail($value, $params = [])
+ protected function sanitizeEmail($value)
{
return sanitize_email($value);
}
- protected function sanitizeFileName($value, $params = [])
+ protected function sanitizeFileName($value)
{
- return sanitize_file_name($value, $params = []);
+ return sanitize_file_name($value);
}
- protected function sanitizeKey($value, $params = [])
+ protected function sanitizeKey($value)
{
return sanitize_key($value);
}
- // protected function sanitizeMeta($value)
- // {
- // return sanitize_meta($value);
- // }
-
- protected function sanitizeHtmlClass($value, $params = [])
+ protected function sanitizeHtmlClass($value)
{
return sanitize_html_class($value);
}
- // protected function sanitizeOption($value)
- // {
- // return sanitize_option($value);
- // }
- // protected function sanitizeTermField($value)
- // {
- // return sanitize_term_field($value);
- // }
-
- protected function sanitizeText($value, $params = [])
+ protected function sanitizeText($value)
{
return sanitize_text_field($value);
}
- protected function sanitizeTitle($value, $params = [])
+ protected function sanitizeTitle($value)
{
return sanitize_title($value);
}
- protected function sanitizeUser($value, $params = [])
+ protected function sanitizeUser($value)
{
return sanitize_user($value);
}
- protected function sanitizeUrl($value, $params = [])
+ protected function sanitizeUrl($value)
{
return esc_url_raw($value);
}
- protected function sanitizeTrim($value, $params = [])
+ protected function sanitizeTrim($value)
{
return is_string($value) ? trim($value) : $value;
}
- protected function sanitizeEscape($value, $params = []): string
+ protected function sanitizeEscape($value): string
{
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
- protected function sanitizeCapitalize($value, $params = []): string
+ protected function sanitizeCapitalize($value): string
{
return ucwords(strtolower($value));
}
@@ -119,7 +104,7 @@
foreach ($keys as $key) {
// Move to the next level in the hierarchy
- if (!isset($currentLevel[$key])) {
+ if (! isset($currentLevel[$key])) {
$currentLevel[$key] = [];
}
$currentLevel = &$currentLevel[$key];
--- a/bit-smtp/vendor/bitapps/wp-validator/src/Validator.php
+++ b/bit-smtp/vendor/bitapps/wp-validator/src/Validator.php
@@ -1,5 +1,4 @@
<?php
-
namespace BitAppsSMTPDepsBitAppsWPValidator;
use BitAppsSMTPDepsBitAppsWPValidatorExceptionMethodNotFoundException;
@@ -23,8 +22,8 @@
public function make($data, $ruleFields, $customMessages = null, $attributeLabels = null)
{
- $this->_data = $data;
- $this->_customMessages = $customMessages;
+ $this->_data = $data;
+ $this->_customMessages = $customMessages;
$this->_attributeLabels = $attributeLabels;
$this->inputContainer = new InputDataContainer($data);
@@ -55,16 +54,16 @@
return [$field];
}
- $nestedKeyQueue = explode('.', $field);
+ $nestedKeyQueue = explode('.', $field);
$visitedFieldKeys = [];
- $dataByKey = (array) $this->_data;
+ $dataByKey = (array) $this->_data;
while ($head = array_shift($nestedKeyQueue)) {
if (trim($head) === '*') {
- $keys = array_keys((array) $dataByKey);
+ $keys = array_keys((array) $dataByKey);
$dataByKey = count($keys) && array_key_exists($keys[0], $dataByKey) ? $dataByKey[$keys[0]] : [];
} else {
- $keys = [$head];
+ $keys = [$head];
$dataByKey = array_key_exists($head, $dataByKey) ? $dataByKey[$head] : [];
}
@@ -106,36 +105,41 @@
public function validateByRules($fieldKey, $value, $rules): void
{
+ $validationRules = [];
+
foreach ($rules as $ruleName) {
if (is_string($ruleName) && strpos($ruleName, 'sanitize') !== false) {
- $this->applyFilter($ruleName, $fieldKey, $value);
-
- continue;
+ $value = $this->applyFilter($ruleName, $value);
+ $this->inputContainer->setAttributeValue($value);
+ } else {
+ $validationRules[] = $ruleName;
}
+ }
+ foreach ($validationRules as $ruleName) {
if (is_subclass_of($ruleName, Rule::class)) {
$ruleClass = is_object($ruleName) ? $ruleName : new $ruleName();
} else {
list($ruleName, $paramValues) = $this->parseRule($ruleName);
- $ruleClass = $this->resolveRule($ruleName);
+ $ruleClass = $this->resolveRule($ruleName);
}
$ruleClass->setInputDataContainer($this->inputContainer);
$ruleClass->setRuleName($ruleName);
- if (!empty($paramValues)) {
+ if (! empty($paramValues)) {
$ruleClass->setParameterValues($ruleClass->getParamKeys(), $paramValues);
}
$isValidated = $ruleClass->validate($this->inputContainer->getAttributeValue());
- if (!$isValidated) {
+ if (! $isValidated) {
$this->errorBag->addError($ruleClass, $this->_customMessages);
break;
}
- if (in_array('present', $rules) && $this->isEmpty($value)) {
+ if ($ruleName === 'present' && $this->isEmpty($value)) {
break;
}
}
@@ -143,7 +147,7 @@
public function fails(): bool
{
- return !empty($this->errorBag->getErrors());
+ return ! empty($this->errorBag->getErrors());
}
public function errors()
@@ -158,7 +162,7 @@
private function resolveRule($ruleName)
{
- if (!is_string($ruleName)) {
+ if (! is_string($ruleName)) {
throw new RuleErrorException('Rule name must be string ');
}
@@ -167,7 +171,7 @@
. str_replace(' ', '', ucwords(str_replace('_', ' ', $ruleName)))
. 'Rule';
- if (!class_exists($ruleClass)) {
+ if (! class_exists($ruleClass)) {
throw new RuleErrorException(sprintf('Unsupported validation rule: %s.', $ruleName));
}
@@ -176,9 +180,9 @@
private function parseRule($rule): array
{
- $exp = explode(':', $rule, 2);
+ $exp = explode(':', $rule, 2);
$ruleName = $exp[0];
- $params = [];
+ $params = [];
if (isset($exp[1])) {
$params = explode(',', $exp[1]);
@@ -187,30 +191,25 @@
return [$ruleName, $params];
}
- private function applyFilter(string $sanitize, $fieldName, $value): void
+ private function applyFilter($sanitize, $value)
{
$data = explode('|', $sanitize);
$sanitizeName = isset($data[0]) ? explode(':', $data[0]) : [];
- $params = isset($data[1]) ? explode(',', $data[1]) : [];
+ $params = isset($data[1]) ? explode(',', $data[1]) : [];
if (count($sanitizeName) === 2) {
list($prefix, $suffix) = $sanitizeName;
- $sanitizationMethod = $prefix . str_replace('_', '', ucwords($suffix, '_'));
+ $sanitizationMethod = $prefix . str_replace('_', '', ucwords($suffix, '_'));
- if (!method_exists($this, $sanitizationMethod)) {
+ if (! method_exists($this, $sanitizationMethod)) {
throw new MethodNotFoundException($sanitizationMethod);
}
- $sanitizedValue = $this->{$sanitizationMethod}($value, $params);
-
- $keys = explode('.', trim($fieldName, '[]'));
- if (count($keys) > 1) {
- $this->setNestedElement($this->validated, $keys, $sanitizedValue);
- } else {
- $this->validated[$fieldName] = $sanitizedValue;
- }
+ $value = $this->{$sanitizationMethod}($value, $params);
}
+
+ return $value;
}
private function setValidatedData($field, $data, $value): void
--- a/bit-smtp/vendor/composer/installed.php
+++ b/bit-smtp/vendor/composer/installed.php
@@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'bitapps/bit-smtp',
- 'pretty_version' => '1.2.2',
- 'version' => '1.2.2.0',
- 'reference' => '7c344d5c1f22459178c39d12c83619e619fc8bf7',
+ 'pretty_version' => '1.2.3',
+ 'version' => '1.2.3.0',
+ 'reference' => 'cd6391207f5d06a885e6a47d2103a9caee8e651e',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -11,9 +11,9 @@
),
'versions' => array(
'bitapps/bit-smtp' => array(
- 'pretty_version' => '1.2.2',
- 'version' => '1.2.2.0',
- 'reference' => '7c344d5c1f22459178c39d12c83619e619fc8bf7',
+ 'pretty_version' => '1.2.3',
+ 'version' => '1.2.3.0',
+ 'reference' => 'cd6391207f5d06a885e6a47d2103a9caee8e651e',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -29,9 +29,9 @@
'dev_requirement' => false,
),
'bitapps/wp-kit' => array(
- 'pretty_version' => '2.1',
- 'version' => '2.1.0.0',
- 'reference' => '3e49d25e047530a2a43c08af3a8fc821feaa7ae8',
+ 'pretty_version' => '2.2',
+ 'version' => '2.2.0.0',
+ 'reference' => '6052fcfd1b94ccb452d2cb4ecfd93e63617503e3',
'type' => 'library',
'install_path' => __DIR__ . '/../bitapps/wp-kit',
'aliases' => array(),
@@ -47,9 +47,9 @@
'dev_requirement' => false,
),
'bitapps/wp-validator' => array(
- 'pretty_version' => '1.2.1',
- 'version' => '1.2.1.0',
- 'reference' => '294d6a7c35436419060dc067f58a9c5a0d72b37e',
+ 'pretty_version' => '1.2.2',
+ 'version' => '1.2.2.0',
+ 'reference' => '856b3685c6e6673af4e3f7fea5083500ce011b99',
'type' => 'library',
'install_path' => __DIR__ . '/../bitapps/wp-validator',
'aliases' => array(),